How to input data from external file into struct array in function

Hey everybody, I am super stuck on an assignment and need help just for the start of it. For the assignment I'm supposed to store information from text files into struct arrays.

What I am given
- enum program types.
- struct for nameType with first name, middle initial, and last name
- struct for studentType with name, ID, email, GPA, and program
- external files (classroster.txt) & (studentlist.txt)
- functions with parameters

This is the classroster.txt

20
Maleeha K Galloway 12832 smallpaul@optonline.net
Autumn J Oconnell 18704 noahb@yahoo.ca
Chaya R Hampton 19628 ralamosm@aol.com
Victoria W Searle 10114 dimensio@gmail.com
Deborah Q Barnett 18172 martink@optonline.net
Maja P Allison 13427 mirod@gmail.com
Darren B Wade 10121 metzzo@yahoo.ca
Amba C Whittington 12673 parksh@yahoo.com
Elisha P Medina 16115 improv@outlook.com
Renesmae Y Crane 17940 dkrishna@optonline.net
Jaiden E Kearns 14066 gavinls@yahoo.com
Lily L Espinoza 10204 dinther@live.com
Pippa Q Chamberlain 15084 qrczak@outlook.com
Keagan N West 19430 doche@verizon.net
Krisha O Montgomery 17526 biglou@gmail.com
Karl E Linebaugh 17156 mosses@live.com
Silva T Pressey 14606 corrada@hotmail.com
Anthony L Contreras 19425 mlewan@aol.com
Gordon G Cisneros 17928 cyrus@live.com
Azul X Rich 16185 jguyer@aol.com

What I am trying to figure out at the moment and what I am stuck on. I am only trying to work on the readClassRoster function at this point.
- Am I declaring my structs okay?
- What does the & on ifstream and int allow me to do?
- When and where do should I put ifstream...
- How do I input the things from the external file into arrays in nameType for first name, middle initial, and last name, which in turn will be used as the name variable in studentType?
- How do I go about inputting the next objects from the external files such as ID and email?
- When the function is finished, how should I go about calling it in main?

Things I've tried and issues caused.
- Using a for loop to input into something like in >> nameType[i].firstName. I have also tried other variations of this but they always return an "expected primary expression before...

Thanks to anyone who took the time to read and help out. I understand that the program doesn't even do anything but I just need the file input figured out. I'm not asking for the solution but an explanation and a "walkthrough" would be helpful. Thanks!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

const int ARRAY_SIZE = 20;

enum programType {CSCI, DBMS, INFM, SDEV};

struct nameType
{
    string firstName;
    char middleInitial;
    string lastName;
};

struct studentType
{
    nameType name;
    int ID;
    string email;
    int GPA;
    programType program;
};

void readClassRoster(ifstream&, studentType[], int&);
void readProgramGPA(ifstream&, studentType[], int);
int findStudentByID(int, const studentType[], int);
double findHighestGPA(const studentType[], int);
void printHighestGPA(double, const studentType[], int);

int main()
{
    
	
	return 0;
}

void readClassRoster(ifstream&, studentType[], int&)
{

    
}

void readProgramGPA(ifstream&, studentType[], int)
{
    
}

int findStudentByID(int, const studentType[], int)
{
    return 0;
}

double findHighestGPA(const studentType[], int)
{
    return 0;
}

void printHighestGPA(double, const studentType[], int)
{
    
}
Last edited on
Hello domweng,

Apparently you did not get much out of http://www.cplusplus.com/forum/beginner/277667/

Although you did post 1 of the 2 input files to work with.

You still need to work on "main" and the "readClassRoster" should be dealing with the file stream unless it is required to define the stream in "main" and pass it to the function.

This looks to be a class assignment and in that case it is best to post the complete instructions that you were given, so that there is no questions on what to do.

to give you an idea:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
constexpr int ARRAY_SIZE{ 20 };  // <--- C++11 on updated version.

const enum programType { CSCI, DBMS, INFM, SDEV };  // <--- As a global variable it should be a constant.

struct StudentName
{
    string firstName;
    char middleInitial;
    string lastName;
};

struct StudentInfo
{
    StudentName name;   // <--- "name" can hold a first name, middle initial and a last name. This is OK
    std::string ID;
    std::string email;
    int GPA;  // <--- Should this be a "double"?
    programType program;
};

using STUDENT_INFO = StudentInfo[ARRAY_SIZE];

int readClassRoster(STUDENT_INFO& studentInfo, int& num);  // <--- As per the TheIdeasMan variable names here do help, but not required. 

In the forward declaration, (prototype), I am not sure what "num" is for, but I used it for now. It should have a better name to describe what it is used for.

In your first post for the "readClassRoster" function you used a for loop to read the file. This can work, but not the way it is. I would be more likely to use a while loop.

If you take what I showed you in the first post and combine it with what I did here you will have a good start.

After that I would highlight lines 46 to the end and put a comment on them. After the first function is working uncomment lines 46 - 49 and work on that function.

It may not be required for the program, but you can consider a "PrintAll" type function just to print the array of structs. The idea is just to see what you have. You may or may not use this, but it will help with other functions.

Andy
Hi Andy, I appreciate the help but it was late at night and I was a little emotional when I posted that so I decided to post a more detailed post, I appreciate all the help :)
Here is the assignment desc

Write a program that uses two structures Name and Student to store the following information for multiple students:

Create a nameType structure that consists of
First Name,
Middle Initial, and
Last Name
Create a studentType structure that contains student information (Include the nameType structure within the Student information structure):
Name
ID
email
GPA
Program (an enum type named programType containing programs such as CSCI, DBMS, INFM, SDEV)
Suppose that a class has at most 20 students. Use an array of 20 components of type studentType. You will read in the names, id, and email from classroster.txt download. The first line of the file will tell you how many students are in the class. To get the the GPA and program for each student you will need to read from studentlist.txt download. The second file will have the id, program, and GPA for all of the students in the department. That means that not every student from studentlist.txt will be in classroster.txt. You will need to only add GPA and program for the students in the class.

Your program must contain at least the following functions (the function prototypes are provided in the starter code):

A function to read the students’ data into the array.

This function will open classroster.txt.
The file is in the format first name, middle initial, last name, student id, email
A function to assign the relevant program and GPA to each student.

This function will open studentlist.txt.
You will have to search the student array to find the student from the file and assign their program and GPA.
If a student from the file is not found in the array skip it and go to the next student in the file.
Programs are encoded as single character codes C = CSCI, S = SDEV, D = DBMS, I = INFM
A function to find a student by id in the array.
This function should do a search on the array and return the position of the student with a matching student id, or -1 if the student is not in the array.
A function to find the highest GPA.

A function to print the names of the students having the highest GPA.

Other than declaring the variables and opening the input and output files, the function main should only be a collection of function calls.
Hello domweng,

To answer your questions:

- Am I declaring my structs okay?


No. The instructions say:

Create a nameType structure that consists of


This refers to the type of struct that will contain name information, but in no way does it say or imply that this be the name of the struct.

From my first response:

For the struct "nameType" consider "StudentName". It is more descriptive of what it is. And for "studentType" consider "StudentInfo". A good name will help to spot errors or problems.




- What does the & on ifstream and int allow me to do?


This means the "ifstream" is being passed by reference, which is the only way that it can be passed. Along with the "int" variable they both mean you are using the variable where it was first defined before it was passed to the function.

If you are stuck with defining the file stream in "main" and have to pass it to the function then some of what I have said may no longer apply.


- When and where do should I put ifstream...


Refer to the above answer for now until I have a chance to go over the instructions better and understand them. It is starting to look as though you are stuck with certain parts of the program.


- How do I input the things from the external file into arrays in nameType for first name, middle initial, and last name, which in turn will be used as the name variable in studentType?


This can be a little difficult to understand because you have a struct that contains a struct. Dealing with the name the code would be something like: studentInfo[idx].name.firstName. And then "firstName" would change to "middleInitial" and then "lastName"

For the other fields the only difference is that you do not need the ".name" part.


- How do I go about inputting the next objects from the external files such as ID and email?


See above answer.


- When the function is finished, how should I go about calling it in main?


See my answer in http://www.cplusplus.com/forum/beginner/277667/#msg1198481 That would be the last bit of code at the bottom.

I will take a better look at the directions and see what you can do.

Andy
Okay I've figured out how to call the function

Now just need to know how to input the stuff, because again, it's giving me an "expected primary expression..."

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

const int ARRAY_SIZE = 20;

enum programType {CSCI, DBMS, INFM, SDEV};

struct nameType
{
    string firstName;
    char middleInitial;
    string lastName;
};

struct studentType
{
    nameType name;
    int ID;
    string email;
    double GPA;
    programType program;
};

void readClassRoster(ifstream&, studentType[], int&);


int main()
{
    studentType student[ARRAY_SIZE];
    ifstream in;
    int students;
    
    readClassRoster(in, student, students);
    
    
    

    
    
	
	return 0;
}

void readClassRoster(ifstream& in, studentType[], int& studentNum)
{
    in.open("classroster.txt");
    in >> studentNum;
    
    for(int i = 0; i < ARRAY_SIZE; i++)
    {
        in >> studentType[i].name.firstName;   
    }
    

    
}
Hello domweng,

This is what I would do with your code, but it is still up to you.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <string>

#include <fstream>

using namespace std;

//const int ARRAY_SIZE = 20;
constexpr int ARRAY_SIZE{ 20 };

const enum programType { CSCI, DBMS, INFM, SDEV };

struct StudentName
{
    string firstName;
    char middleInitial;
    string lastName;
};

struct StudentInfo
{
    StudentName name;
    int ID;
    string email;
    double GPA;
    programType program;
};

void readClassRoster(ifstream& inFile, StudentInfo studentInfo[], int& RecordCount);


int main()
{
    StudentInfo student[ARRAY_SIZE];

    ifstream inFile;

    int recordCount;

    readClassRoster(inFile, student, recordCount);







    return 0;
}

void readClassRoster(ifstream& inFile, StudentInfo studentInfo[], int& recordCount)
{
    inFile.open("classroster.txt");

    inFile >> recordCount;
    // <--- But how do you know that it is open and usable?

    for (int i = 0; i < ARRAY_SIZE; i++)  // <--- If you are reading the 1st line of the file into
                                          // "recordCount" you should use this instead of
                                          // "ARRAY_SIZE" beause "recordCount" could be lessThan "ARRAY_SIZE".

    {
        inFile >> studentInfo[i].name.firstName;  // <--- "StudentInfo" is the struct name not a variable.
                                                  // Otherwise a good start.
    }
}

I can not stress enough that a good variable name usually a verb, but sometimes a noun that describes what it is used for or what it does is best. Unfortunately teaching about good variable names is not part of the classes. I believe they consider this to be OJT, (On the Job Training).

Just because the directions say Create a nameType structure does not mean that is what you should call the struct. Calling the struct "nameType" is misleading. Think about what the struct is and the information it is holding.

One problem I do see is the "readClassRoster" and the "readProgramGPA" are both "void" functions which can be a problem if a file stream does not open. You can only return to "main", but would have no way of knowing that the program needs to end.

You were given some code to start with, the prototypes, but are you required to use it the way it is or can you adjust as needed?

Andy

Figured out my issue by myself, really appreciate it Andy, I'll most likely be posting a new post for my next issue lol.
Topic archived. No new replies allowed.