简体   繁体   中英

Newline changes how strings read from file are printed in C++

After the text file is read from ifstream to save each line to a vector of strings, it is supposed to be printed out using for loop but it only shows the last line when there is no newline at the end of cout.

I tried the two scenarios to print out the vector of strings: 1) cout << s; 2) cout << s << '\\n';

where s is a string of the vector that iterates every loop. 1) only showed the last line whereas 2) showed the entire text.

ifstream inFile("sample.txt");
string str;
vector<string> strings;

while (getline(inFile, str))
    strings.push_back(str);

for (auto s : strings)
    std::cout << s;

The sample text is:

Test File
The quick brown fox jumps over the lazy dog.

cout << s; only printed:

The quick brown fox jumps over the lazy dog.

cout << s << '\\n'; printed:

Test File
The quick brown fox jumps over the lazy dog.

I expected the second result when executing the first case. How does newline change the result of output other than the newline itself?

EDITED : Since getline() stops when it reaches newline and does not read newline either, cout without \\n should have printed Test FileThe quick brown fox jumps over the lazy dog if the program was executed on Windows . Because ifstream works on text mode that converts \\r\\n into \\n .

However, since I'm using g++ installed on cygwin, that is unlikely to happen. That is the reason why Test File\\r\\nThe quick brown fox jumps over the lazy dog only shows The quick brown fox jumps over the lazy dog .

Simply put, \\r makes the output line return to the original point, and that truncated the text before \\r .

Try with cout << s << endl;

Possibly you are using a library, IDE or debugger that sets up iostream in order to flush only at new line.

You can try also with cout << s << flush , and note that endl is like a \\n character plus a flush.

On Windows, text files are generally stored with lines separated by a carriage return (CR) followed by a line feed (LF). If the file is opened in binary mode, you will get both of those characters when reading in the text.

So getline , which splits on the '\\n' (which is almost certainly the same value as a LF), gives you lines that end in CR ( '\\r' ).

When you print a CR, the console may return the cursor to the beginning of the current row. Then you print the next line and what you originally printed is overwritten. Since, in your case, the first line was shorter than the second, it made it appear as those the first line was missing.

The problem with that explanation is that

ifstream inFile("sample.txt");

opens the file in text mode, not binary mode. So the CR+LF should be reduced to '\\n' and it should work.

Some possible explanations are:

  1. The code you've shown is not exactly the same as the code you're using and that inFile is actually opened in binary mode.

  2. The sample.txt file has already been mangled and has lines that end in CR+CR+LF.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM