С++ получить размер (в байтах) EOL

Я читаю текстовый файл ASCII. Он определяется размером каждого поля в байтах. Например. Каждая строка состоит из 10 байтов для некоторой строки, 8 байтов для значения с плавающей запятой, 5 байтов для целого числа и так далее.

Моя проблема заключается в чтении символа новой строки, который имеет переменный размер в зависимости от ОС (обычно 2 байта для Windows и 1 байт для Linux, я думаю).

Как я могу получить размер символа EOL в С++?

Например, в питоне я могу сделать:

len(os.linesep)

person jramm    schedule 05.01.2016    source источник
comment
Если вы открываете файл в текстовом режиме, новые строки всегда должны быть просто '\n', каким бы ни было исходное окончание строки. Вам действительно нужно знать размер собственной строки EOL?   -  person Badministrator    schedule 05.01.2016
comment
Гарантированно ли, что файл был сохранен в той же ОС, что и код, который его читает? Если да, просто откройте файл в текстовом (не двоичном) режиме.   -  person dxiv    schedule 05.01.2016


Ответы (2)


Проверенный временем способ сделать это — прочитать строку.

Теперь последний символ должен быть \n. Раздели его. Затем посмотрите на предыдущий символ. Это будет либо \r, либо что-то еще. Если это \r, разденьте его.

Для текстовых файлов Windows [ascii] других возможностей нет.

Это работает, даже если файл смешанный (например, некоторые строки \r\n, а некоторые просто \n).

Вы можете предварительно сделать это в нескольких строках, просто чтобы убедиться, что вы не имеете дело с чем-то странным.

После этого вы теперь знаете, чего ожидать от большей части файла. Но полосовой метод является общенадежным способом. В Windows вы можете импортировать файл из Unix (или наоборот).

person Craig Estey    schedule 05.01.2016
comment
Наполовину придирка, но трудно read a line, не зная заранее, что такое разделитель строки. Например, ваш рецепт не работает для разделителей строк \r, а также для последовательных пустых строк, сохраненных как \r\n\n\n, которые были замечены в среде Windows. - person dxiv; 05.01.2016
comment
@dxiv Этот метод работает против \r\n\n\n (например, \r\n \n \n) - это просто смешанный режим, как я уже упоминал [последовательный не проблема]. Я не видел файла только \r более 20 лет [если вообще видел, а я преобразовал 1000 файлов]. Не читается многими программами, так как теперь они предполагают [по крайней мере] новую строку. Попробуйте DOS type file на одном ;-) Я не думаю, что даже MS их больше поддерживает. '\r' допустим [как не терминатор] в начале строки (например, захваченный вывод прогресса). Я видел гораздо больше таких (например, \rpgm is 56% done\rpgm is 57% done) - person Craig Estey; 05.01.2016
comment
@CraigEstey - файлы Mac старой школы имеют только \r. См. википедию: en.wikipedia.org/wiki/Newline - person user3690202; 11.01.2016
comment
@ user3690202 Я так и догадался, но это выходит за рамки вопроса ОП. Такой файл необходимо будет преобразовать при импорте в [NTFS] FS, чтобы его можно было использовать в WinX, поэтому OP никогда не увидит их в необработанном виде. Они могут быть обнаружены/преобразованы автоматически, но лучше просто знать [через опцию строки cmd]. Самый быстрый способ чтения строк — через mmap (см. мой ответ: stackoverflow.com/questions/33616284/), так что достаточно просто предварительно отсканировать сначала, но вряд ли стоит лишнего усилий в 99,44% случаев. - person Craig Estey; 12.01.2016
comment
@CraigEstey - я могу придумать много способов получить текстовые файлы с завершением CR. Вы можете загрузить машину с Windows с помощью загрузочного диска Linux и скопировать файлы со старого диска и т. Д. Дело в том, что нигде в OP не упоминаются окна, копирование файла на машину с Windows не импортирует в FS, черт возьми, Vim может генерировать строку CR окончание текстовых файлов на компьютере с Windows, если вы действительно этого хотите. Это не выходит за рамки вопроса - на самом деле кажется, что вся суть вопроса, точка, которую вы упустили. - person user3690202; 12.01.2016
comment
@user3690202 user3690202 Я ничего не пропустил, мой друг. vim [под Windows] сгенерирует \r\n [vim называет это режимом dos], и я рассмотрел этот случай смешанного режима в своем посте. Вы можете включить/выключить режим DOS в любой системе. Это отличается от \r only, которые искажены в WinX/unix и должны быть преобразованы, прежде чем любая обычная/разумная программа сможет их использовать. OP упоминает окна - перечитайте вопрос. Время двигаться дальше... - person Craig Estey; 12.01.2016
comment
@CraigEstey Я думаю, вам нужно научиться использовать Vim и одновременно узнать, как работают окончания строк. vim.wikia.com/wiki/File_format установите формат файла на Mac, и все будет работать нормально. Полная ерунда, что вы говорите о том, что он уродлив / Неважно, у таких людей, как вы, нет способности учиться. Может быть, перейти к учебнику — 20-летний опыт, ха, должно быть, тогда пропустил MacOS 9, а? - person user3690202; 12.01.2016

Я не уверен, что перевод происходит там, где вы думаете. Посмотрите на следующий код:

ostringstream buf;
buf<< std::endl;
string s = buf.str();
int i = strlen(s.c_str());

После этого, работая в Windows, я == 1. Таким образом, определение конца строки в std равно 1 символу. Как уже отмечали другие, это символ "\n".

person user3690202    schedule 05.01.2016
comment
Этот код неверен, потому что CRT lib не превращает \n в \r\n для буферов в памяти, но делает это для файлов и консоли. - person Serge Rogatch; 05.01.2016
comment
Здесь вы демонстрируете проблему, с которой я столкнулся. C++ будет преобразовывать \n в характерный для ОС символ при записи в файл/консоль, но не в буфер. - person jramm; 05.01.2016
comment
@jramm Я не думаю, что вы еще достаточно хорошо объяснили свою проблему. \n не нужно (и фактически не может) кодироваться при записи в буфер. Но когда вы записываете этот буфер в файл, открытый в текстовом режиме, \n будет автоматически преобразовано в то, что требует платформа. Затем, если вы откроете тот же файл в режиме text и прочитаете его обратно, последовательность новой строки будет преобразована обратно в \n. Так что, по крайней мере, мне непонятно, зачем вам знать кодировку \n в файле на диске. - person dxiv; 05.01.2016