For every and any input operation, you must check the return value; otherwise you cannot know whether the operation succeeded and what it did.
If you are reading into a fixed buffer, you need to check the stream object and the count of extracted characters:
file.getline(buffer, sizeof buffer);
auto n = file.gcount();
if (file) {
std::cout << "Read line with " << n << " characters: '";
std::copy_n(buffer, n, std::ostream_iterator<char>(std::cout));
std::cout << "'\n";
} else if (n > 0) {
std::cout << "Read incomplete line with prefix '";
std::copy_n(buffer, n, std::ostream_iterator<char>(std::cout));
std::cout << "'.\n";
file.clear();
} else {
std::cout << "Did not read any lines.\n";
}
Note that the extracted count (file.gcount()
) includes the null terminator, which basic_istream::getline
writes into the output buffer. (So the maximal length of a line that can be read completely is sizeof(buffer) - 1
.)
Alternatively, you can read into a dynamic string. This means that memory will be automatically allocated to hold each complete line, but it's a lot easier to reason about:
for (std::string line; std::getline(file, line); ) {
std::cout << "Read one line: '" << line << "'\n";
}
Here we only check the success of the input operation, and we do this inside the loop condition. The number of extracted characters (this time excluding the null terminator) is precisely line.size()
after the successful read.