Reputation: 138
I use std::fstream to read text files line by line with the member function getline(). It uses buffer of limited size, and sometimes lines on input are longer than the buffer. After the first reading of the long line getline()
stopped read data, what was surprise for my after the debug of the code. The documentation states, that reading of the long line set the error flag **failbit
, **it is described as usual situation, not runtime error or fatal failure (https://cplusplus.com/reference/istream/istream/getline/). Documentation does not point any attention to this flag and does not describe, how to deal with long lines.
Do you know any documented way, how to precess long lines ? It should be, as this behaviour affect all class std::fstream, but I never see any descriptions or discussions.
The example of the program:
#include <fstream>
#include <iostream>
#include <string>
int main(){
char buffer[10];
std::string filename{"test.txt"};
auto file=std::fstream(filename, std::ios_base::in | std::ios_base::binary );
if(file.is_open()){
size_t readBites{4};
file.getline(buffer,readBites);
auto length=std::strlen(buffer);
auto lengthStream=file.gcount();
std::cout << "Read "<<length<<"/"<<lengthStream<<":"<<buffer<<std::endl;
file.getline(buffer,readBites);
length=std::strlen(buffer);
lengthStream=file.gcount();
std::cout << "Read "<<length<<"/"<<lengthStream<<":"<<buffer<<std::endl;
}
return 0;
}
If test.txt file contains, for example:
1234567890
ABCDEFGHIJK
I expected output (like fgets(...)
in C):
Read 3/3:123
Read 3/3:456
but it really is :
Read 3/3:123
Read 0/0:
I use limited size of buffer, as it is requirement of the client software, calling this code, it can be any size and processes long lines in short buffer.
Upvotes: 0
Views: 123
Reputation: 596226
As the documentation you linked to says:
The failbit flag is set if the function extracts no characters, or if the delimiting character is not found once (n-1) characters have already been written to
s
.
So, if you try to read more data than your buffer can hold, the stream's failbit
state is set:
Either the delimiting character was not found or no characters were extracted at all (because the end-of-file was before the first character or because the construction of
sentry
failed).
At that point, the stream won't read any more data:
Internally, the function accesses the input sequence by first constructing a
sentry
object (withnoskipws
set to true). Then (ifgood
), it extracts characters from its associated stream buffer object as if calling its member functionssbumpc
orsgetc
, and finally destroys thesentry
object before returning.
Since the stream is no longer in a good
state, it stops extracting characters. You have to clear()
the stream to return it to a good
state.
Upvotes: 4