read in using getline - empty row at the end?

Greetings!

In a book (using C++ 14) there was an example about reading from files using getline. I implemented the following method:
1
2
3
4
5
6
7
8
9
10
11
12
vector <double> read_dataset(string datafile){
	ifstream datasource(datafile);
	vector <double> Xdata;
	string row;
	while (datasource.good()){
		getline(datasource, row);
		cout<<row<<endl;
		Xdata.push_back(stod(row));
		cout<<"Done"<<endl;
	}
return Xdata;
}

The data I want to read is a 1-column csv file storing double values, so in each row there is only one number, no white space, delimiters or anything else.
The code above, however, extracts an empty row after all other rows have been read in, and then crashes due to stod used on an empty row. There is, however, no empty row at the end of my file. What is going on?
Try writing the while statement at line 5 as while (getline(datasource, row)), deleting line 6.

And I really recommend NOT having using namespace std; in your code. One day it will bite you in the tuchas and it will be painful. Get used to explicitly using namespace designations.

https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice

PLUS, whitespace is your friend. Use it liberally. Jamming up code like std::cout<<"Done"<<std::endl; is hard to read.

std::cout << "Done" << std::endl; or std::cout << "Done\n";
Thanks George,

your recommendation works like a charm. Any idea what went wrong? I would like to put a little warning comment next to the example in the book.

Since I barely use anything but std (and I am lazy), I tend to use using namespace std; . But it can't hurt to get used to "good practice" ahead of time I guess as I expect to do more with C++ over the years...
Even when std::getline reads the last line in the file its status is still good. So your original code went and read another line that didn't exist.

By looping on reading the file when it reaches the end and tries another read it fails, loop ends before adding what is bogus data to the std::vector.
Cheers George, I get it!
What year was the book published, its title and who is/are the author(s)?

A lot of C/C++ programming books to be frank are garbage and have a lot of "this is how C does it" notions disguised as half-arsed C++ code.

You want a good C++ book that teaches C++ from beginner to expert, that also teaches C++20 as well as general C++ ideas?

Beginning C++20: From Novice to Professional
https://www.amazon.com/gp/product/1484258835/

Not all compilers are 100% C++20 compliant yet, Visual Studio is the only one I know of.
https://en.cppreference.com/w/cpp/compiler_support/20

GCC/MinGW, Clang just aren't there yet.

Not having module support really cheeses me.

There are a few other books I can recommend that are more narrow in focus, such as the details of what C++20 has to offer, the history and uses of lambdas, the details of C++17, etc.

See also:
https://isocpp.org/wiki/faq/how-to-learn-cpp#buy-several-books
Last edited on
Is there a reason why you read a double as a string and convert it to double?
Why not reading doubles?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
std::vector<double> read_dataset(std::string datafile)
{
	std::ifstream datasource(datafile);
	std::vector <double> Xdata;
	
	if (!datasource)
	{
	  std::cout << "Error opening file\n";
	  return Xdata;
	}
	double input;
	while (datasource >> input)
	{
	  	Xdata.push_back(input);
	  	datasource.ignore(255, '\n'); // consume trailing \n
		std::cout << input << std::endl;
	}
	std::cout<< "Done" << std::endl;
  return Xdata;
}
Is there a reason why you read a double as a string and convert it to double?

Because "that's how The Book does it." :)

Experience and time will reveal better ways to code. :D
Just to show how bad books can be a supposedly authorative book I have in my C++ library on an early C++ standard known as ANSI C++ (copyright 1996 by Sams Publishing) has their "Hello World" introduction program as:
1
2
3
4
5
6
#include <iotream.h>

void main()
{
   cout << "Hello World!" << endl;
}

<iostream.h> was legal at one time, now it isn't.

void main() has NEVER been legal C/C++, but the authors use it all through the book. No int main() anywhere.

*SPIT!*
Last edited on
1
2
3
4
5
6
7
8
auto read_dataset(const std::string& datafile) {
	std::vector<double> Xdata;

	if (std::ifstream datasource {datafile})
		for (double data {}; datasource >> data; Xdata.push_back(data));

	return Xdata;
}


where caller deals with no data by checking returned vector for .empty()
@George - not the one by Lauren Boyd?
Because "that's how The Book does it." :)

Somehow I missed that.
@seeplus,

The book on ANSI C++ is by Jesse Liberty and J. Mark Hord. Another 'Sams' tome, "Teach Yourself ANSI C++ in 21 Days, Premier Edition."

The book even mentions ANSI C++ was still in draft at the time the book was written, but PUH-LEEZE! void main()?!?
Oh Jesse Liberty - not a fan. His last book re C++ was published 2016 regarding learning C++14 in 24 Hours
Yeah, the Sams C++ books went from learning C++ in 21 days to learning in one hour a day.

Jesse Liberty as author was replaced by Siddharta Rao for the C++ books.
The book I use is written by a German CS professor and only has a German edition (just realized the latter). In case you still want to take a look, this is the website to the book: http://www.cppbuch.de/
I use the C++14 version published in 2015. I liked it because it is very beginner friendly and does not expect any programming or CS knowledge whatsoever. It also comes with a large collection of exercises and solutions.

I also tried another book:
https://www.amazon.com/Discovering-Modern-Scientists-Programmers-Depth/dp/0134383583/ref=sr_1_2?keywords=Discovering+Modern+C%2B%2B+-+Peter+Gottschling&qid=1645492436&s=books&sr=1-2
But this one kept skipping concepts and turned out to be very difficult to digest (for a beginner).

Thanks for the recommends anyway!
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
/*
 The data I want to read is a 1-column csv file storing double values.
 */

#include <iostream>
#include <fstream>

#include <vector>

using namespace std; // Something to draw crabs :)

int main ()
{
    double value;
    vector<double> vector_of_doubles;
    
    ifstream  myfile ("doubles.csv");
    if (myfile.is_open())
    {
        while ( myfile >> value )
        {
            vector_of_doubles.push_back(value);
            cout << value << " is now in the vector\n";
        }
        cout << '\n';
        
        myfile.close();
    }
    else
    {
        cout << "ERROR: Unable to open file";
        return -9;
    }
    
    // Display vector contents - there are MANY ways to do this
    for(int i = 0; i < vector_of_doubles.size(); i++)
    {
        cout << vector_of_doubles[i] << '\n';
    }
    cout << '\n';
    
    return 0;
}


Data file called double .csv follows.

Note that the cs in csv stands for comma separated which doesn't mean much of significance here unless each line is terminated with a ',' which would be unorthodox and, as you say, isn't. But who knows for absolute certainty without a sample provided.


1.234
23.7
19
267.089



1.234 is now in the vector
23.7 is now in the vector
19 is now in the vector
267.089 is now in the vector

1.234
23.7
19
267.089

Program ended with exit code: 0
There are a couple of websites I would recommend for learning C++, both free.

The tutorial here at CPlusPlus:
http://www.cplusplus.com/doc/tutorial/

It is a bit out-dated.

Another tutorial that is updated, Learn C++:
https://www.learncpp.com/

Both are English language, if that matters to you.

The best advice I can give is keep coding, learn from any mistakes you make, try to solve any problem by doing research first doing 'net searches and above all else ask questions.

Show you made an effort to do the work yourself, and most people here will be eager to help.

The SSCCE Rule works.
http://www.sscce.org/

Also, realize when asking "how do I do this?" you will get 20 different answers from 8 different people. :)

Put on your asbestos undergarments if a The One True Way To Code flame war breaks out.
The book on Amazon has a newer version available now, published a couple of months ago back in December 2021 instead of 2015.
https://www.amazon.com/Discovering-Modern-Depth-Peter-Gottschling-dp-0136677649/dp/0136677649/

Translating the German to English on your first book link shows it is a C++20 book now.
Topic archived. No new replies allowed.