2016-01-05 7 views
8

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

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

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

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

len(os.linesep) 
+4

Если вы открываете файл в текстовом режиме, символы новой строки всегда должны быть '' \ n'', независимо от того, заканчивается ли родная строка. Вам действительно нужно знать размер родной строки EOL? – Badministrator

+0

Является ли файл гарантированным сохранением в той же ОС, что и ваш код, который его читает? Если да, просто откройте файл в текстовом (не бинарном) режиме. – dxiv

ответ

0

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

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

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

+0

Этот код неверен, потому что CRT lib не превращает '\ n' в' \ r \ n' для буферов в памяти, но он делает это для файлов и консоли. –

+0

Здесь вы демонстрируете проблему, против которой я против. C++ преобразует «\ n» в os-специфический символ при записи в файл/консоль, но не в буфер. – jramm

+0

@jramm Я не думаю, что вы достаточно хорошо объяснили свою проблему. '\ n' не нужно (и на самом деле не может) быть закодировано вообще, когда записывается в буфер. Но _ когда вы пишете этот буфер в файл, открытый в режиме * text *, '\ n' будет автоматически переводиться в соответствии с требованиями платформы. Затем, если вы откроете тот же файл в режиме _text_ и прочитаете его, последовательность новой строки будет переведена на '\ n'. Итак, для меня, по крайней мере, непонятно, почему вам нужно знать кодировку '\ n' в файле на диске. – dxiv

1

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

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

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

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

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

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

+0

Половина nitpick, но трудно «прочитать строку», не зная заранее, что такое терминатор линии. Например, ваш рецепт терпит неудачу для терминаторов строк '\ r', а также для последовательных пустых строк, сохраненных как' \ r \ n \ n \ n', которые были замечены в windows-land. – dxiv

+1

@dxiv Метод работает против '\ r \ n \ n \ n' (например,' \ r \ n \ n \ n') - это просто смешанный режим, о котором я упоминал [последовательный не является проблемой]. Я не видел файл '\ r' всего лишь через 20 лет [если и когда-либо, и я преобразовал 1000 файлов].Не читается многими программами, поскольку теперь они предполагают [как минимум] новую строку. Попробуйте DOS 'type file' на одном ;-) Я не думаю, что даже MS поддерживает их больше. '\ r' действителен [как не-терминатор] в _переходе_ строки (например, зафиксированный прогресс). Я видел гораздо больше этого (например, '\ rpgm - 56% сделано \ rpgm - 57% сделано') –

+0

@CraigEstey - файлы старой школы Mac только. См. Wikipedia: https://en.wikipedia.org/wiki/Newline – user3690202