Skip to content

Instantly share code, notes, and snippets.

@josephwb
Created June 4, 2014 15:53
Show Gist options
  • Save josephwb/df09e3a71679461fc104 to your computer and use it in GitHub Desktop.
Save josephwb/df09e3a71679461fc104 to your computer and use it in GitHub Desktop.
C++ getline for when line endings are unknown
// g++ -Wall getlineSafe.cpp -o getlineSafe -O
#include <string.h>
#include <iostream>
#include <fstream>
#include <cstdlib>
std::istream& getlineSafe(std::istream& is, std::string& t) {
t.clear();
// The characters in the stream are read one-by-one using a std::streambuf.
// That is faster than reading them one-by-one using the std::istream.
// Code that uses streambuf this way must be guarded by a sentry object.
// The sentry object performs various tasks,
// such as thread synchronization and updating the stream state.
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 EOF:
// Also handle the case when the last line has no line ending
if (t.empty()) {
is.setstate(std::ios::eofbit);
}
return is;
default:
t += (char)c;
}
}
}
int main(int argc, char *argv[]) {
std::string path;
if (argc == 1) {
std::cout << "Usage: ./safeLine filename" << std::endl;
return EXIT_FAILURE;
} else {
path = argv[1];
}
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 (!getlineSafe(ifs, t).eof()) {
++n;
}
ifs.close();
std::cout << "The file contains " << n << " lines." << std::endl;
return EXIT_SUCCESS;
}
@josephwb
Copy link
Author

josephwb commented Jun 4, 2014

Useful for when variously dealing with mac/unix/windows input files.
Taken from Stack Overflow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment