voxoid
voxoid

Reputation: 1289

c++ getline reads entire file

I'm using std::getline() to read from a text file, line by line. However, the first call to getline is reading in the entire file! I've also tried specifying the delimeter as '\n' explicitly. Any ideas why this might be happening?

My code:

std::ifstream serialIn;
...
serialIn.open(argv[3]);
...
std::string tmpStr;
std::getline(serialIn, tmpStr, '\n');
// All 570 lines in the file is in tmpStr!
...
std::string serialLine;
std::getline(serialIn, serialLine);
// serialLine == "" here

I am using Visual Studio 2008. The text file has 570 lines (I'm viewing it in Notepad++ fwiw).

Edit: I worked around this problem by using Notepad++ to convert the line endings in my input text file to "Windows" line endings. The file was written with '\n' at the end of each line, using c++ code. Why would getline() require the Windows line endings (\r\n)?? Does this have to do with character width, or Microsoft implementation?

Upvotes: 2

Views: 5260

Answers (2)

jamesdlin
jamesdlin

Reputation: 89926

You're confusing the newline you see in code ('\n') with the actual line-ending representation for the platform (some combination of carriage-return (CR) and linefeed (LF) bytes).

The standard I/O library functions automatically convert line-endings for your platform to and from conceptual newlines for text-mode streams (the default). See What's the difference between text and binary I/O? from the comp.lang.c FAQ. (Although that's from the C FAQ, the concepts apply to C++ as well.) Since you're on Windows, the standard I/O functions by default write newlines as CR-LF and expect CR-LF for newlines when reading.

If you don't want these conversions done and would prefer to see the raw, unadulterated data, then you should set your streams to binary mode. In binary mode, \n corresponds to just LF, and \r corresponds to just CR.

In C, you can specify binary mode by passing "b" as one of the flags to fopen:

FILE* file = fopen(filename, "rb"); // Open a file for reading in binary mode.

In C++:

 std::ifstream in;
 in.open(filename, std::ios::binary);

or:

 std::ifstream in(filename, std::ios::binary);

Upvotes: 3

Nitzan Shaked
Nitzan Shaked

Reputation: 13598

Just guessing, but could your file have Unix line-endings and you're running on Windows?

Upvotes: 6

Related Questions