В частности, меня интересует istream& getline ( istream& is, string& str );
. Есть ли опция для конструктора ifstream, чтобы сообщить ему преобразовать все кодировки новой строки в '\n' под капотом? Я хочу иметь возможность вызывать getline
и корректно обрабатывать все окончания строки.
Обновление. Чтобы уточнить, я хочу, чтобы иметь возможность писать код, который компилируется практически в любом месте, и будет принимать входные данные практически из любого места. Включая редкие файлы, которые имеют "\ r" без "\n" . Минимизация неудобств для любых пользователей программного обеспечения.
Легко обойти эту проблему, но мне все еще интересно, как правильно, в стандарте, гибко обрабатывать все форматы текстовых файлов.
getline
читает полную строку, вплоть до '\n', в строку. "\n" потребляется из потока, но getline не включает его в строку. До сих пор это было хорошо, но может быть "\ r" перед "\n" , который входит в строку.
Есть три типа окончаний строк, которые видны в текстовых файлах: '\n' является условным окончанием на машинах Unix, '\ r' был (я думаю) использован в старых операционных системах Mac, а Windows использует пару, '\ r', следующую за '\n'.
Проблема заключается в том, что getline
оставляет символ \r в конце строки.
ifstream f("a_text_file_of_unknown_origin");
string line;
getline(f, line);
if(!f.fail()) { // a non-empty line was read
// BUT, there might be an '\r' at the end now.
}
Изменить Благодаря Нилу, указав, что f.good()
не то, что я хотел. !f.fail()
- это то, что я хочу.
Я могу удалить его вручную (см. редактирование этого вопроса), что легко для текстовых файлов Windows. Но я беспокоюсь, что кто-то будет кормить файл, содержащий только "\ r" . В этом случае я предполагаю, что getline будет потреблять весь файл, считая, что это одна строка!
.. и что даже не рассматривая Unicode: -)
.. возможно Boost имеет хороший способ потреблять по одной строке за раз из любого типа текстового файла?
Изменить Я использую это, чтобы обрабатывать файлы Windows, но я все еще чувствую, что мне не нужно! И это не будет fork для файлов \r'-only.
if(!line.empty() && *line.rbegin() == '\r') {
line.erase( line.length()-1, 1);
}