diff --git a/xylib/bruker_spc.cpp b/xylib/bruker_spc.cpp index c172854..776a6c1 100644 --- a/xylib/bruker_spc.cpp +++ b/xylib/bruker_spc.cpp @@ -67,7 +67,7 @@ void BrukerSpcDataSet::load_data(std::istream &f, const char* path) #endif if (par_file) { std::string line; - while (std::getline(par_file, line, '\r')) { + while (getline_with_any_ending(par_file, line) && !par_file.eof()) { std::string key, value; str_split(line, ' ', key, value); if (value.find('\n') == std::string::npos) diff --git a/xylib/util.cpp b/xylib/util.cpp index f8d59ba..f45af5f 100644 --- a/xylib/util.cpp +++ b/xylib/util.cpp @@ -261,6 +261,32 @@ bool get_valid_line(std::istream &is, std::string &line, char comment_char) return true; } +// get line ending with \r, \n or \r\n +// based on https://stackoverflow.com/a/6089413/104453 +std::istream& getline_with_any_ending(std::istream& is, std::string& t) +{ + t.clear(); + std::istream::sentry se(is, true); + std::streambuf* sb = is.rdbuf(); + for (;;) { + int c = sb->sbumpc(); + if (c == '\n') + return is; + if (c == '\r') { + if (sb->sgetc() == '\n') + sb->sbumpc(); + return is; + } + if (c == std::streambuf::traits_type::eof()) { + // Also handle the case when the last line has no line ending + if (t.empty()) + is.setstate(std::ios::eofbit); + return is; + } + t += (char)c; + } +} + void skip_whitespace(istream &f) { diff --git a/xylib/util.h b/xylib/util.h index 9c47e21..4843217 100644 --- a/xylib/util.h +++ b/xylib/util.h @@ -57,6 +57,7 @@ bool has_word(const std::string &sentence, const std::string &word); std::string read_line(std::istream &is); bool get_valid_line(std::istream &is, std::string &line, char comment_char); +std::istream& getline_with_any_ending(std::istream& is, std::string& t); void skip_whitespace(std::istream &f); Column* read_start_step_end_line(std::istream& f);