Gracefully Handling Different Line Endings in std::istream::getline
When reading text files, encountering varying line endings such as 'n', 'r', and 'rn' can pose challenges. std::getline is a convenient function for retrieving lines from an input stream, but it may leave residual 'r' characters at the end of the string.
As pointed out by Neil, the C runtime is generally equipped to handle line ending conventions based on the platform. However, interoperability between different systems requires a more robust approach.
Here's a customized function that seamlessly processes all three line ending types:
std::istream& safeGetline(std::istream& is, std::string& t) { t.clear(); std::istream::sentry se(is, true); std::streambuf* sb = is.rdbuf(); for(;;) { int c = sb->sbumpc(); switch (c) { case '\n': return is; case '\r': if(sb->sgetc() == '\n') sb->sbumpc(); return is; case std::streambuf::traits_type::eof(): if(t.empty()) is.setstate(std::ios::eofbit); return is; default: t += (char)c; } } }
In this function, we utilize a streambuf object to read characters one by one efficiently. Each character is examined, and based on its type, appropriate actions are taken to handle line endings.
A sample test program illustrates the usage of safeGetline:
int main() { std::string path = ... // Insert path to test file here std::ifstream ifs(path.c_str()); if(!ifs) { std::cout << "Failed to open the file." << std::endl; return EXIT_FAILURE; } int n = 0; std::string t; while(!safeGetline(ifs, t).eof()) ++n; std::cout << "The file contains " << n << " lines." << std::endl; return EXIT_SUCCESS; }
By employing this approach, you can confidently read text files from various origins, ensuring graceful handling of different line endings.
The above is the detailed content of How to Gracefully Handle Different Line Endings in C 's `std::getline`?. For more information, please follow other related articles on the PHP Chinese website!