How to compare two values from two different text files?

Pages: 12
Hey everyone, I'm pretty stuck right now on this assignment. So I got my read from the first file okay but then I need to compare if the ID gotten from the first file (4th row in classroster.txt) matches any of the ID's from the second file (1st row in studentlist.txt). I need to check it for each of the ID's given by the first file/info[i].ID. So how to I insert the first row's values from the second file and use them in a comparative way, like an if(info[i].ID != ...) I don't really know anything helps.

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

studentlist.txt //

19425 S 1.97
19487 C 3.66
18704 I 3.16
16185 S 2.52
18172 D 3.22
14503 I 3.77
12673 C 3.50
19442 S 1.55
11840 C 3.44
14482 S 3.70
17305 C 3.99
17156 I 2.74
12190 S 3.99
16124 S 3.20
12813 C 2.73
17022 C 2.82
16115 D 3.58
19903 I 3.07
14994 I 3.38
17283 C 2.85
19558 D 1.89
18924 I 1.41
17940 D 3.99
18359 D 2.96
10121 I 2.79
19621 I 3.99
14085 D 1.04
10114 S 3.09
12832 S 2.10
12168 S 1.50
17928 I 3.30
19430 S 3.99
18181 S 1.01
12559 C 2.42
10521 I 3.03
15889 D 1.00
14606 C 3.43
10204 S 3.21
18262 I 3.23
17596 C 1.93
17526 S 2.68
14066 I 3.07
19628 D 2.78
11367 C 3.43
13062 C 1.93
13427 S 2.00
16436 C 3.61
15084 I 3.08
19972 I 3.11
18941 D 1.47

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
67
68
69
70
71
72
  #include <iostream>
#include <fstream>
#include <string>

using namespace std;

const int ARRAY_SIZE = 20;

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

struct studentType
{
    nameType name;
    int ID;
    string email;
    double GPA;
    enum programType {CSCI, DBMS, INFM, SDEV};
    
}info[ARRAY_SIZE];

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

int main()
{
    studentType student[ARRAY_SIZE];
    ifstream in;
    int students;
    
    ifstream out;
    
    readClassRoster(in, student, students);
    readProgramGPA(out, student, students);
    
	return 0;
}

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

    
}

void readProgramGPA(ifstream& out, studentType[], int studentNum)
{
    out.open("studentlist.txt");

    for(int i = 0; !out.eof(); i++)
    {
        
        
        
    }
    
}



Do you mean that overall you should do:
FOR each ID in classroster.txt
  IF ID is in studentlist.txt
  THEN what

The "ID is in studentlist.txt" could be rephrased "studentlist.txt contains ID".
It could be nice to do that with std::find or std::find_if
http://www.cplusplus.com/reference/algorithm/find_if/

If "students" is just a container of ID's from studentlist.txt, then the "contains" test:
1
2
3
4
auto it = std::find( students.begin(), students.end(), ID );
if ( it != students.end() ) {
  std::cout << "ID " << ID << " from roster is in list of students\n"
}
@keskiverto,

See http://www.cplusplus.com/forum/beginner/277683/#msg1198531 for directions.

Right idea except the names in lines 1 and 2 are backwards.

Andy
Alright guys I tried that but then it starts giving me errors such as

1. student was not declared in this scope
2. ID was not declared in this scope
3a. did you mean beg()
4a. cannot use functions beg()/beginning() and end()

I even tried including the libraries of #vector % #algorithm
Hello domweng,

You should keep 1 topic going even if you have new questions. Right now you have 3 different topics with different bits of information making it difficult for anyone to follow.

1
2
3
4
5
6
7
8
9
struct studentType
{
    nameType name;
    int ID;
    string email;
    double GPA;
    enum programType {CSCI, DBMS, INFM, SDEV};
    
}info[ARRAY_SIZE];  // <--- Global variable. Bad idea, but find out the hard way. 

I do have 1 question that is perplexing me. For "struct studentType" what makes a type and where do you get that information to know if you should store it?

You can read "studentlist.txt" 1 line at a time and put each field in a variable. Then you will need to check if the ID from "studentlist.txt" is in the array that you just made.

If it is deal with the single letter and the GPA as you need to. If no match read the next line and repeat.

Whether you can use keskiverto's code is up to you based on what you know.

Andy
To answer your question, I'm not sure what you mean by makes a type but I set the variables types to what they're accepting then get that info from a for loop which stores the data for them from the classroster.txt, which I'm having no issues passing that information around my code and using it in the second function.

So how to I put the ID information gotten from studentlist.txt into an array, with skipping the letter for class and the GPA (because it screws the code up and causes a segmentation fault). Should I create a separate struct to store the info from studentlist.txt? Make a multi-dimensional array? Or is there just a way to skip it?

Also how do I skip a line if it doesn't match the ID from classroster.txt (file[i].ID) and the ID information gotten from studentlist.txt

Hello domweng,


To answer your question, I'm not sure what you mean by makes a type


I think you are misunderstanding what I said because you are misunderstanding the directions.


So how to I put the ID information gotten from studentlist.txt into an array, with skipping the letter for class and the GPA (because it screws the code up and causes a segmentation fault). Should I create a separate struct to store the info from studentlist.txt? Make a multi-dimensional array? Or is there just a way to skip it?


First go back and understand your directions:

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.

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.

Then look at your prototypes.

The function prototype: void readProgramGPA(ifstream&, studentType[], int); Really could use some variable names here will read the file "studentlist.txt" then call the function: int findStudentByID(int, const studentType[], int) to actually search the array. I used a simple for loop here to return the index of the array or (-1) if nothing was found.

In the first function if the returned index is > -1 use the index, I call it "idx" for short, to set the values in the array. I used a switch:
1
2
3
4
5
switch (code)
{
    case 'C':
        studentInfo[idx].program = CSCI;
        break;

For now I just called it "code" because it was quick. Should have a better name.

The line above the code should be a hint to use an if statement.

The output I get is:

                     STUDENT INFORMATION
--------------------------------------------------------------

  Id |        Name             | GPA |      E-mail
--------------------------------------------------------------

12832 Maleeha K, Maleeha         2.10  smallpaul@optonline.net
18704 Autumn J, Autumn           3.16  noahb@yahoo.ca
19628 Chaya R, Chaya             2.78  ralamosm@aol.com
10114 Victoria W, Victoria       3.09  dimensio@gmail.com
18172 Deborah Q, Deborah         3.22  martink@optonline.net
13427 Maja P, Maja               2.00  mirod@gmail.com
10121 Darren B, Darren           2.79  metzzo@yahoo.ca
12673 Amba C, Amba               3.50  parksh@yahoo.com
16115 Elisha P, Elisha           3.58  improv@outlook.com
17940 Renesmae Y, Renesmae       3.99  dkrishna@optonline.net
14066 Jaiden E, Jaiden           3.07  gavinls@yahoo.com
10204 Lily L, Lily               3.21  dinther@live.com
15084 Pippa Q, Pippa             3.08  qrczak@outlook.com
19430 Keagan N, Keagan           3.99  doche@verizon.net
17526 Krisha O, Krisha           2.68  biglou@gmail.com
17156 Karl E, Karl               2.74  mosses@live.com
14606 Silva T, Silva             3.43  corrada@hotmail.com
19425 Anthony L, Anthony         1.97  mlewan@aol.com
17928 Gordon G, Gordon           3.30  cyrus@live.com
16185 Azul X, Azul               2.52  jguyer@aol.com


Still need to add the "program" to the output.

Andy
Got his far and then get a segmentation dump because of the difference in (ifstream& in) & (ifstream& out) is there a way around, I tried changing the out to in but still screws it up.

1
2
3
4
5
6
7
8
9
10
11
12
13
void readProgramGPA(ifstream& out, studentType[], int studentNum)
{
    out.open("studentlist.txt");
    int studentID[50];
    
    for(int i = 0; !out.eof(); i++)
    {
        out >> studentID[i] >> info[i].program >> info[i].GPA;
        
    }
    
    
}
Hello domweng,

Why are you calling an "ifstream", (input stream), out?

Did you mean to pass an "ofstream"?

On line 8 you are trying to write to an input stream.

Andy
Because when I change it to this...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void readProgramGPA(ifstream& in, studentType[], int studentNum)
{
    in.open("studentlist.txt");
    int studentID[50];
    
    for(int i = 0; !in.eof; i++)
    {
        in >> studentID[i] >> info[i].program >> info[i].GPA;
        cout << studentID[i] << info[i].program << info[i].GPA << endl;
        
        
    }
    
    
}


The !in.eof doesn't work and the data just turns to random numbers.
Hello domweng,

In line 1 is "studentType" the name of the struct or the name of the variable?

In line 8 you are reading into "info[i]", but where is "info" defined?

Your function needs 3 variables: int ID, char program and double GPA.

Read into these variables then call another function passing the array and the ID to search for. If a match is found return the index otherwise return -1.

Then use an if statement to determine if "idx" is > than -1 and if true set the variables in the array. I used a switch to set "program" making use of the enum.

Your for loop can be made to work, but I used a while loop because it was easier.

The problem you are having with !in.eof is that you are checking this before you read the file which would set the "eof" bit. When the inside of the loop sets "eof" you are still going to process nothing before it adds 1 to "i" and checks for "eof".

I refer you to what I said earlier.

I revised the print function and now have this:

                     STUDENT INFORMATION
--------------------------------------------------------------

  Id |        Name            | PROGRAM | GPA |      E-mail
--------------------------------------------------------------

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


 Press Enter to continue:



Andy
Here's what I have right now, am I at least on the right track? When I go any farther I just mess it up, I'm unfortunately at the point of just giving up I'm making no progress and just sitting her guessing-and-checking being unproductive with no prevail :/

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

const int ARRAY_SIZE = 50;

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

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

struct studentType
{
    nameType name;
    int ID;
    string email;
    double GPA;
    char program;
    
}info[ARRAY_SIZE];

void readClassRoster(ifstream& in, studentType[], int& studentNum);
void readProgramGPA(ifstream& out, studentType[], int studentNum);
int findStudentByID(int studentID, const studentType[], int studentNum);


int main()
{
    int students;
    studentType student[ARRAY_SIZE];
    
    ifstream in;
    readClassRoster(in, student, students);
    
    ifstream out;
    readProgramGPA(out, student, students);
    
    
    
    
	return 0;
}

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

    
}

void readProgramGPA(ifstream& out, studentType[], int studentNum)
{
    out.open("studentlist.txt");
    int studentID;
    
    while(!out.eof())
    {
        out >> studentID;
        out.ignore(1000, '\n');
    }



}

int findStudentByID(int studentID, const studentType[], int studentNum)
{
    
    
    
    
    return 0;
}
This will read the classroster file into the student array, read the studentlist file and merge this data into the student array when id's match and then display the resulting student array.

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>

constexpr size_t ARRAY_SIZE {50};

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

struct NameType {
	std::string firstName;
	char middleInitial {};
	std::string lastName;
};

struct StudentType {
	NameType name;
	unsigned ID {};
	std::string email;
	double GPA {};
	char program {};
};

struct Gpa {
	unsigned ID {};
	char program {};
	double GPA {};
};

size_t readClassRoster(StudentType info[]);
bool readProgramGPA(StudentType info[]);
int findStudentByID(unsigned studentID, const StudentType[]);
void displayInfo(const StudentType info[], size_t noStud);

std::istream& operator>>(std::istream& ifs, NameType& nt)
{
	return ifs >> nt.firstName >> nt.middleInitial >> nt.lastName;
}

std::istream& operator>>(std::istream& ifs, StudentType& st)
{
	return ifs >> st.name >> st.ID >> st.email;
}

std::istream& operator>>(std::istream& ifs, Gpa& gpa)
{
	return ifs >> gpa.ID >> gpa.program >> gpa.GPA;
}

std::ostream& operator<<(std::ostream& ofs, const NameType& nt)
{
	return ofs << std::left << std::setw(15) << nt.firstName << ' ' << nt.middleInitial << "   " << std::setw(15) << nt.lastName;
}

std::ostream& operator<<(std::ostream& ofs, const StudentType& st)
{
	return ofs << st.ID << ' ' << st.name << ' ' << st.program << "  " << std::fixed << std::setprecision(2) << st.GPA << "   " << st.email;
}

int main()
{
	StudentType student[ARRAY_SIZE] {};

	const auto noStud {readClassRoster(student)};

	if (noStud == 0)
		return (std::cout << "Cannot open class file\n"), 1;

	if (!readProgramGPA(student))
		return (std::cout << "Cannot open gpa file\n"), 2;

	displayInfo(student, noStud);
}

size_t readClassRoster(StudentType info[])
{
	size_t studentNum {}, read {};

	std::ifstream in("classroster.txt");

	if (in && in >> studentNum)
		for (; read < ARRAY_SIZE && read < studentNum && in >> info[read]; ++read);

	return read;
}

bool readProgramGPA(StudentType info[])
{
	std::ifstream stud("studentlist.txt");

	if (!stud)
		return false;

	for (Gpa gpa; stud >> gpa; )
		if (const auto indx {findStudentByID(gpa.ID, info)}; indx >= 0) {
			info[indx].GPA = gpa.GPA;
			info[indx].program = gpa.program;
		}

	return true;
}

int findStudentByID(unsigned studentID, const StudentType info[])
{
	for (size_t i = 0; i < ARRAY_SIZE; ++i)
		if (info[i].ID == studentID)
			return i;

	return -1;
}

void displayInfo(const StudentType info[], size_t sze)
{
	for (size_t i = 0; i < sze; ++i)
		std::cout << info[i] << '\n';

	std::cout << '\n';
}



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

Hello domweng,


Here's what I have right now, am I at least on the right track?


About half.


When I go any farther I just mess it up, I'm unfortunately at the point of just giving up I'm making no progress and just sitting her guessing-and-checking being unproductive with no prevail :/


That is because you are not listing. I have told you what you can do and given you a push in the right direction, but you appear to ignore what you are told.

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

const int ARRAY_SIZE = 50;

enum programType { CSCI, DBMS, INFM, SDEV };  // <--- should be a constant.

struct nameType  // <--- Bad name.
{
    string firstName;
    char middleInitial;
    string lastName;
};

struct studentType  // <--- Bad name.
{
    nameType name;
    int ID;
    string email;
    double GPA;
    char program;

}info[ARRAY_SIZE];  // <--- Bad idea to use a global variable. Should be avoided.

void readClassRoster(ifstream& in, studentType[], int& studentNum);  // <--- Very helpful to use variable names here. Same for the others.
void readProgramGPA(ifstream& out, studentType[], int studentNum);
int findStudentByID(int studentID, const studentType[], int studentNum);


int main()
{
    int students;
    studentType student[ARRAY_SIZE];  // <--- Defined, passed to the functions, but never used. This is where it should be defined and the array that you should used.

    ifstream in;  // <--- Could use a better name. I like to use "inFileClassRoster" or for short "inFileCR".
    readClassRoster(in, student, students);

    ifstream out;  // <--- Why are you calling an input stream "out"? Here you could use something like "inFileStudList".
    readProgramGPA(out, student, students);


    return 0;
}

void readClassRoster(ifstream& in, studentType[], int& studentNum)  // <--- Receiving an array from "main", but never used.
{
    in.open("classroster.txt");
    // <--- How do you know if the file is open and usable? You do not. You are just hoping it is.

    in >> studentNum;

    // <--- This works, but it is not the best. "studentNum" could be wrong or you may not have 20 records in the file.
    // A potential problem.

    for (int i = 0; i < studentNum; i++)
    {
        in >> info[i].name.firstName >> info[i].name.middleInitial >> info[i].name.lastName >> info[i].ID >> info[i].email;
    }
}

void readProgramGPA(ifstream& out, studentType[], int studentNum)
{
    out.open("studentlist.txt");
    int studentID;

    while (!out.eof())  // <--- Does not work the way that you are thinking.
    {
        out >> studentID;  // <--- You have 3 fields to read, but you are only reading 1 and ignoring the rest. Is there a reason?
        out.ignore(1000, '\n');

        // <--- Needs to call "findStudentByID" to search the array.
    }
}

int findStudentByID(int studentID, const studentType[], int studentNum)
{


    return 0;
}


Andy
@Handy Andy

Okay I've decided to restart my progress and try to reread what you've told me, I'm just having trouble learning without being shown the solution/example so that's what I'm asking for for these questions, your choice which you want to give.

1. You say don't use a global variable instead of the info[ARRAY_SIZE] so how do I make that array local and use it around my code, i.e. inputting into with external file, passing around by reference? Where should that be located and what should it look like?

2. Should I make a separate array/struct to retain the information brought in by classroster.txt? What should that look like and where should that array be placed?

3. What is the int I should use in my, findStudentByID references?

4. Where should my enum for programType be placed, in the struct of studentType or in the global space?

Some information for you

1. I don't know if it's my IDE but I'm not allowed to make an enum a constant.


Hello domweng,


1. You say don't use a global variable instead of the info[ARRAY_SIZE] so how do I make that array local and use it around my code, i.e. inputting into with external file, passing around by reference? Where should that be located and what should it look like?


Actually you have done this just not correctly.
1
2
3
4
int main()
{
    int students;
    studentType student[ARRAY_SIZE];  // <--- Defined, passed to the functions, but never used. This is where it should be defined and the array that you should used. 

What you could do is:
1
2
3
4
5
6
7
int main()
{
    int students;
    studentType student[ARRAY_SIZE];  // <--- Defined, passed to the functions, but never used. This is where it should be defined and the array that you should used.

studentType info[ARRAY_SIZE];

What I would suggest is:
1
2
3
4
int main()
{
    int students;
    studentType students[ARRAY_SIZE];  // <--- Defined, passed to the functions, but never used. This is where it should be defined and the array that you should used. 

"students" would be a better name than "info". It better describes what the array is used for.


2. Should I make a separate array/struct to retain the information brought in by classroster.txt?


You could, but if yo do this in the function it will be lost when the function ends and destroys all the local variables. Not the best approach.


3. What is the int I should use in my, findStudentByID references?


There are actually 2 "int"s used in the "findStudentByID" function. The first "int" comes from reading the "studentlist.txt" file. The second one is from the array of structs.

When I came to understand the instructions better I came up with this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int readProgramGPA(STUDENT_INFO& studentInfo, int recordCount)
{
    const std::string inFileName{ "studentlist.txt" };  // <--- Put File name here.

    inFile.open(inFileName);

    if (!inFile)
    {
        std::cout << "\n\n     File " << std::quoted(inFileName) << " did not open.\n\n";
        //std::cout << "\n\n     File \"" << inFileName << "\" did not open.\n\n";

        return 2;
    }

    char code{};
    int ID{}, idx{};
    double GPA{};
    
    while (inFile >> ID >> code >> GPA)
    {
        idx = findStudentByID(ID, studentInfo, recordCount);

        if (idx > -1)

I do not understand why or what should be returned by the function, but I made use of it for now.

Line 21 is what is most important. Should the if statement evaluate to true "idx" is used to make all the needed changes to what is in the array.

This function is fairly simple:
1
2
3
4
5
6
7
8
9
10
11
12
int findStudentByID(int studIDToFind, const STUDENT_INFO& studentInfo, int recordCount)
{
    for (int idx = 0; idx < recordCount; idx++)
    {
        if (studIDToFind == studentInfo[idx].ID)
        {
            return idx;
        }
    }

    return -1;
}

This is the rare occasion when I change a variable name in a function because it makes more sense in the function.


4. Where should my enum for programType be placed, in the struct of studentType or in the global space?

1. I don't know if it's my IDE but I'm not allowed to make an enum a constant.


I would keep this as a global variable as you first wrote it. Upon some research https://en.cppreference.com/w/cpp/language/enum I found that the names inside the {}s are assigned "constexpr" values which would eliminate the need for defining the "enum" as a "const".

Andy
Okay I got this far and my program is searching just fine (I even had it read out the found indexes).

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
void readProgramGPA(ifstream& out, studentType[], int studentNum)
{
    out.open("studentlist.txt");
    int studentID;
    studentType student[NUM_STUDENTS];
    
    for(int i = 0; !out.eof(); i++)
    {
        out >> studentID >> info[i].program >> info[i].gpa;
        
        findStudentByID(studentID, student, studentNum);
    }
    
}

int findStudentByID(int studentID, const studentType[], int studentNum)
{
    for (int idx = 0; idx < studentNum; idx++)
    {
        if(studentID == info[idx].id)
        {
            return idx;
        }
    }
    
    return -1;
}


When I try doing an int idx = function call... it returns the -1's as well, so how am I able to pass on the idx values returned to my other function and use them as positioning to insert in the other items (class and GPA)?
You have to test the returned value to know whether it is -1 or a valid index.
Last edited on
@keskiverto

This is where I'm at at the moment, I'm just doing cout << idx just to see what the value is at and it comes out to zero. Is this normal? If not could you show me what I'm doing wrong.

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
void readProgramGPA(ifstream& out, studentType[], int studentNum)
{
    out.open("studentlist.txt");
    int studentID;
    studentType student[NUM_STUDENTS];
    int idx;
    
    for(int i = 0; !out.eof(); i++)
    {
        out >> studentID >> info[i].program >> info[i].gpa;
        
        findStudentByID(studentID, student, studentNum);
        cout << idx << endl;
    }
    
}

int findStudentByID(int studentID, const studentType[], int studentNum)
{
    int idx;
    bool found = false;
    
    for (int idx = 0; idx < studentNum; idx++)
        if(studentID == info[idx].id)
        {
            found = true;
            break;
        }
        
        if(found)
        {
            return idx;
        }    
        else
        {
            return -1;
        }
}
Hello domweng,

Nice attempt, but does not wot even with keskiverto's suggestion.

On line 5 you are creating a new array of "students" that is empty and has no values entered except what you try to enter on line 9.

On line 9 you are trying to read from an output stream.

Line 10 passes this new array to the "find" function which will never find a match based on what you just read and what you put into the new array.

In line 1 and 16 the parameter, studentType[], should be a compiler error or at least a warning because you did ot give it a variable name nor do you use them in the functions. You are probably still using that global variable.

In "main" you need:
1
2
3
4
5
6
7
int main()  // <--- "main" is empty. Program does nothing.
{
    int recordCount{};  // <--- The "cin" ALWAYS initialize all your variables.
    Student_Info studentInfo[NUM_STUDENTS];

// <--- Eventually the function call would be.
readProgramGPA(in, studentInfo, studentNum);

And the function deffinition would be:
 
void readProgramGPA(ifstream& in, studentType studentInfo[], int studentNum)

This would give you access to the array that should be defined in "main".

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
// <--- Given the input fields 19425 S 1.97.
// You need 3 regular variables to read the file into.

// Based on the instructions "open and check that the file is open".

// If the file is ready I defined these variables:

//char programCode{};
//int ID{}, idx{};
//double GPA{};

// I used a while loop to read the file.
//   inside the loop I started with "idx = findStudentByID(ID, studentInfo, recordCount);".

// This is where keskiverto's comes into play.
//   if (idx > -1)

// if true use "idx" to set the value of GPA.

// Then I used a switch based on the "programCode" read from the file.
// In the case statements use the "enum" to set the value of "programCode".

// Not knowing what the returned "int" is for I believe I used it differently than may be expected.

// So the function ends with a "return 0;" 

I am not very good at pseudocode, but that should give you a good idea of what how the "readProgramGPA" should work.

The "findStudentByID" function will work, but you do have to pass it the correct array to use. const studentType[] is not enough. It is missing the variable name. If you are still using the global variable "info" then it will not matter unless it is a compiler error.

Andy
Pages: 12