In the following C++ code, I realised that gcount() was returning a larger number than I wanted, because getline() consumes the final newline character but doesn’t send it to the input stream.
What I still don’t understand is the program’s output, though. For input “Test\n”, why do I get ” est\n”? How come my mistake affects the first character of the string rather than adding unwanted rubbish onto the end? And how come the program’s output is at odds with the way the string looks in the debugger (“Test\n”, as I’d expect)?
#include <fstream>
#include <vector>
#include <string>
#include <iostream>
using namespace std;
int main()
{
const int bufferSize = 1024;
ifstream input( "test.txt", ios::in | ios::binary );
vector<char> vecBuffer( bufferSize );
input.getline( &vecBuffer[0], bufferSize );
string strResult( vecBuffer.begin(), vecBuffer.begin() + input.gcount() );
cout << strResult << "\n";
return 0;
}
I’ve also duplicated this result, Windows Vista, Visual Studio 2005 SP2.
When I figure out what the heck is happening, I’ll update this post.
edit: Okay, there we go. The problem (and the different results people are getting) are from the \r. What happens is you call
input.getlineand put the result in vecBuffer. The getline function strips off the \n, but leaves the \r in place.You then transfer the vecBuffer to a string variable, but use the gcount function from input, meaning you will get one char too much, because the input variable still contains the \n, and the vecBuffer does not.
The resulting strResult is:
So then “Test” is printed, followed by a carriage return (puts the cursor back at the start of the line), a null character (overwriting the T), and finally the \n, which correctly puts the cursor on the new line.
So you either have to strip out the \r, or write a function that gets the string length directly from vecBuffer, checking for null characters.