Why can't this code read the data from the text file and stuck in a loop?

This code does not give the correct answer. Why is this? I just get a the repeating output of


Beginning to read file



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

using namespace std;

int main(int argc, char* argv[])
{
	double x[4] = { 0.0, 1.0, 1.0, 0.0 };
	double y[4] = { 0.0, 0.0, 1.0, 1.0 };

	int columns = 4;

	ofstream file_write_x_and_y_dat("x_and_y.dat");

	file_write_x_and_y_dat.setf(ios::scientific);
	file_write_x_and_y_dat.setf(ios::showpos);
	file_write_x_and_y_dat.precision(10);

	for (int i = 0; i < columns; i++)
	{
		file_write_x_and_y_dat << x[i] << ", ";
		cout << "Writing x [" << x[i] << "] to file x_and_y.dat" << endl;
	}

	file_write_x_and_y_dat << endl;

	file_write_x_and_y_dat.flush();

	for (int i = 0; i < columns; i++)
	{
		file_write_x_and_y_dat << y[i] << ", ";
		cout << "Writing y[" << y[i] << "] to file to file x_and_y.dat" << endl;
	}

	file_write_x_and_y_dat << "\n";
	file_write_x_and_y_dat.close();

	std::ifstream read_file("x_and_y.dat"); 
	
	if (read_file.fail())
	{
		cout << "File has not been opened" << endl;
		return 1;
	}
	else if (read_file.is_open())
	{
		cout << "File has been opened";
	}
	else {
		cout << "Something else is going on" << endl;
	}

	int number_of_rows = 0; 
	
	while (!read_file.eof()) {
		
		double dummy1, dummy2, dummy3, dummy4; 

		cout << "Beginning to read file" << endl;
		read_file >> dummy1 >> dummy2; read_file >> dummy3 >> dummy4; 

		if (read_file.eof())
		{
			cout << "end of file has been reached" << endl;
		}

		number_of_rows++;
	} 

	std::cout << "Number of rows = " << number_of_rows << "\n";
	
	read_file.close();

	return 0;
}
What is the correct answer?

Instead of looping on eof, try looping on the actual extraction of data.

1
2
3
4
5
6
7
double dummy1, dummy2, dummy3, dummy4; // better names???
while (read_file >> dummy1 >> dummy2 >> dummy3 >> dummy4)
{
    std::cout << "Data read successfully, dummy1 = " << dummy1 << "\n";

    number_of_rows++;
}


Edit: On line 22, you're putting commas in your file.
This will cause simple whitespace-delimited extraction with istream operator>> to fail.
If your data is comma delimited, use a combination of getline with comma as the delimiter, and use stod to convert string to double.

http://www.cplusplus.com/reference/string/string/getline/
http://www.cplusplus.com/reference/string/stod/

Or, use istream operator>>, but skip a character for the comma between each use of >>.

1
2
3
	file_write_x_and_y_dat << endl;

	file_write_x_and_y_dat.flush();
endl already flushes the file, so calling it twice in a row is just wasteful.
But you don't need to use endl or flush; it will be done automatically. Doing it more than necessary is just lowering performance.
Last edited on
Something like this, perhaps:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// Example program
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>

int main()
{
    std::string lines_from_file = "1234.45, 67.89, 111.222222, 3283,\n  633.45, -435.89, 0.0001, 10000,";
    std::istringstream file(lines_from_file); // emulating a file stream here
    
    double num1, num2, num3, num4;
    char dummy_comma;

    while (file >> num1 >> dummy_comma
                >> num2 >> dummy_comma
                >> num3 >> dummy_comma
                >> num4 >> dummy_comma)
    {
        std::cout << num1 << " " << num2 << " " << num3 << " " << num4 << '\n';
    }
}
Hello,

With this loop, after removing the commas, (does this have an effect on the eof? seemingly does after my results below)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
	while (!read_file.eof()) {
		
		double dummy1, dummy2, dummy3, dummy4; 

		cout << "Beginning to read file" << endl;
		read_file >> dummy1 >> dummy2; read_file >> dummy3 >> dummy4; 
		cout << dummy1 << dummy2 << dummy3 << dummy4 << endl;
		if (read_file.eof())
		{
			cout << "end of file has been reached" << endl;
		}

		number_of_rows++;
	} 


I get


Writing x [0] to file x_and_y.dat
Writing x [1] to file x_and_y.dat
Writing x [1] to file x_and_y.dat
Writing x [0] to file x_and_y.dat
Writing y[0] to file to file x_and_y.dat
Writing y[0] to file to file x_and_y.dat
Writing y[1] to file to file x_and_y.dat
Writing y[1] to file to file x_and_y.dat
File has been opened
Beginning to read file
0110
Beginning to read file
0011
Beginning to read file
0011
end of file has been reached
Number of rows = 3


With this

1
2
3
4
5
6
while (read_file >> dummy1 >> dummy2 >> dummy3 >> dummy4)
{
    std::cout << "Data read successfully, dummy1 = " << dummy1 << "\n";

    number_of_rows++;
}


I obtain


Writing x [0] to file x_and_y.dat
Writing x [1] to file x_and_y.dat
Writing x [1] to file x_and_y.dat
Writing x [0] to file x_and_y.dat
Writing y[0] to file to file x_and_y.dat
Writing y[0] to file to file x_and_y.dat
Writing y[1] to file to file x_and_y.dat
Writing y[1] to file to file x_and_y.dat
File has been opened
Data read successfully, dummy1 = 0
Data read successfully, dummy1 = 0
Number of rows = 2
Topic archived. No new replies allowed.