get line function, strings and structs

I am trying to read a line from a file and store that line into a string. Once that line is stored into a string, I need to store it into a struct.
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
  #include <iostream>
#include <fstream>
#include <string>

using namespace std;

struct Student{
    string firstName;
    string lastName;
    double grade;
    char letterGrade;
};

Student students[100];

ifstream file1("students.txt");

//stores line from file into a struct
void readLine(ifstream file){

    string line;

    for(int i=0;i<=100;i++){
        getline(file,line);

        line>>students[i].firstName>>students.[i].lastName>>students[i].grade
    }
}
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
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

struct Student {
	string firstName;
	string lastName;
	double grade;
	char letterGrade;
};

int main()
{
	ifstream input("input.txt");
	ofstream output("output.txt");

	Student student_array[100];

	int i = 0;
	while (!input.eof())
	{
		input >> student_array[i].firstName >> student_array[i].lastName >> student_array[i].grade;
		++i;
	}

	input.close();
	output.close();
	return 0;
}
Last edited on
Hello von1997,

HandsomeJohn has a good concept, but looping on the condition of "!input.eof()" is a bad idea. This will not work the way you might think. Usually this will process the last read a second time before the while condition figures out that you have reached end of file.

The more accepted way is:

1
2
3
4
5
6
        int i = 0;
	while (input >> student_array[i].firstName)
	{
		input >> student_array[i].lastName >> student_array[i].grade;
		++i;
	}


But even this could be a problem. Consider a first or last name that has a space in the name. "input" like "cin" will read to the first white space or "\n" whichever comes first. This could through the whole read off.

Right now I am working reading a file, but I am only guessing at what the layout of the file looks like. A sample of the "students.txt" file would help.

Hope this helps for now,

Andy
I am trying to read a line from a file and store that line into a string. Once that line is stored into a string, I need to store it into a struct.

You can use a stringstream to parse the contents of a string into separate variables. I used the same function readLine() as the original code, but changed it to make it work - hopefully as intended.


//stores line from file into a struct
My version attempts to do just that. It reads a line from the file and stores it in a struct. It also return a bool value to indicate whether it succeeded.

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
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>

using namespace std;

struct Student {
    string firstName;
    string lastName;
    double grade;
    char   letterGrade;
};

bool readLine(ifstream & file, Student & s);

int main()
{
    const int MAX_SIZE = 100;
    Student students[MAX_SIZE];

    ifstream file1("students.txt");
    if (!file1)
    {
        cout << "Could not open file\n";
        return 1;
    }
    
    int count = 0;
    
    while (count < MAX_SIZE && readLine(file1, students[count]) )
        ++count;
        
    cout << "Number of records read from file : " << count << '\n';  
    
    for (int i=0; i<count; ++i)
    {
        cout << students[i].firstName << ' '
             << students[i].lastName  << ' '
             << students[i].grade     << ' '
             << students[i].letterGrade << '\n';
    }      
        
}

// stores line from file into a struct
bool readLine(ifstream & file, Student & s) 
{
    string line;
    s.letterGrade = '-';
    
    if ( getline(file,line))
    {
        istringstream ss(line);
        if ( ss >> s.firstName >> s.lastName >> s.grade)
            return true;
    }
    
    return false;
}
Last edited on
Hello von1997,

An alternative to Chervil's idea if your input is one line per field and if a name might contain spaces:

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
#include <iostream>
#include <fstream>
#include <string>
#include <limits>
#include <chrono>
#include <thread>

struct Student
{
	std::string firstName;
	std::string lastName;
	double grade;
	char letterGrade;
};

//stores line from file into a struct
void readLine(std::ifstream& input, Student student_array[])
{

	int i = 0;
	while (std::getline(input, student_array[i].firstName))
	{
		std::getline(input, student_array[i].lastName);

		input >> student_array[i].grade;

		input.ignore(std::numeric_limits<std::streamsize>::max(), '\n');// <--- Requires header file "limits".
		++i;
	}
}

int main()

{

	Student students[100];

	std::ifstream file1("students.txt");

	if (!file1)
	{
		std::cout << "\n File students.txt did not open\n";
		std::this_thread::sleep_for(std::chrono::seconds(3));  // <--- Requires header files "chrono" and "thread".
		exit(1);
	}

	readLine(file1, students);

	return 0;
}


Even if all information is on one line this would work.

Hope that helps,

Andy
Topic archived. No new replies allowed.