чтение unistd.h () функция: Как считать файл линию за линией?

То, что я должен сделать, использовать функцию чтения от unistd.h для чтения файла линию за линией. У меня есть это в данный момент:

n = read(fd, str, size);

Однако это читает в конец файла, или до числа размера байтов. Существует ли способ, которым я могу заставить его считать одну строку за один раз, остановившись в новой строке? Строки являются всей переменной длиной.

Мне разрешают только эти два заголовочных файла:

#include <unistd.h>
#include <fcntl.h>

Точка осуществления должна читать в файле линию за линией и производить каждую строку, как это читается в. В основном, для имитации fgets () и fputs () функции.

8
задан Jonathan Leffler 27 February 2010 в 20:30
поделиться

7 ответов

Вы можете читать символ за символом в буфер и проверять наличие символов разрыва строки ( \ r \ n для Windows и ] \ n для систем Unix).

7
ответ дан 5 December 2019 в 12:57
поделиться

К сожалению, функция чтения не подходит для такого типа ввода. Предполагая, что это какое-то искусственное требование из собеседования / домашнего задания / упражнения, вы можете попытаться смоделировать строковый ввод, прочитав файл по частям и самостоятельно разбив его на символ новой строки, сохраняя состояние каким-то образом между вызовами. Вы можете обойтись без индикатора статического положения, если тщательно задокументируете использование функции.

1
ответ дан 5 December 2019 в 12:57
поделиться

Вы захотите создать буфер, в два раза превышающий длину вашей самой длинной строки, которую вы поддерживаете, и вам нужно будет отслеживать состояние вашего буфера .

По сути, каждый раз, когда вы вызываете новую строку, вы просматриваете текущую позицию в буфере в поисках маркера конца строки. Если найдешь - хорошо, это твоя линия. Обновите указатели буфера и вернитесь.

Если вы достигли максимальной длины, вы вернете усеченную строку и измените свое состояние на «Отмена». В следующий раз, когда вас вызовут, вам нужно сбросить до следующего конца строки, а затем перейти в обычное состояние чтения.

Если вы достигли конца того, что прочитали, вам нужно будет прочитать другие символы maxline, обернувшись до начала буфера, если вы достигнете дна (т. Е. Вам может потребоваться сделать два вызова чтения) а затем продолжите сканирование.

Все вышесказанное предполагает, что вы можете установить максимальную длину строки. Если вы не можете, тогда вам придется работать с динамической памятью и беспокоиться о том, что произойдет, если ошибка malloc буфера не удастся. Кроме того, вам нужно всегда проверять результаты чтения на случай, если вы достигли конца файла при чтении в буфер.

4
ответ дан 5 December 2019 в 12:57
поделиться

Это хороший вопрос, но разрешение только функции чтения не помогает! : P

Вызов цикла чтения для получения фиксированного количества байтов и поиск символа '\ n', затем возврат части строки (до '\ n') и сохранение оставшейся части (кроме '\ n' ), чтобы добавить следующий фрагмент символьного файла.

Использовать динамическую память.

Чем больше размер буфера, тем меньше вызовов чтения (что является системным вызовом, поэтому не дешево, но в настоящее время есть вытесняющие ядра).

...

Или просто установите максимальную длину строки и используйте fgets, если вам нужно побыстрее ...

0
ответ дан 5 December 2019 в 12:57
поделиться

Что ж, оно будет читать построчно с терминала.

У вас есть следующие варианты:

  • Напишите функцию, которая использует чтение, когда заканчиваются данные, но возвращает только одну строку за раз вызывающей стороне
  • Используйте функцию в библиотеке, которая делает именно это: fgets () .
  • Читайте только один байт за раз, чтобы не заходить слишком далеко.
0
ответ дан 5 December 2019 в 12:57
поделиться

Если вы откроете файл в текстовом режиме, то Windows "\ r \ n" будет автоматически переводиться в "\ n" при чтении файла.

Если вы используете Unix, вы можете использовать нестандартную функцию 1 gcc 'getline ()'.


1 Функция getline () является стандартной в POSIX 2008.

0
ответ дан 5 December 2019 в 12:57
поделиться

Если вам нужно прочитать ровно 1 строку (и не выходить за ее пределы) с помощью read () , единственный общепринятый способ сделать это - прочитать 1 байт за time и цикл до тех пор, пока вы не получите байт новой строки. Однако, если ваш файловый дескриптор ссылается на терминал, и он находится в стандартном (каноническом) режиме, чтение будет ждать перехода на новую строку и вернет размер меньше запрошенного, как только строка станет доступной. Однако он может возвращать более одной строки, если данные поступают очень быстро, или менее 1 строки, если буфер вашей программы или внутренний буфер терминала короче, чем длина строки.

Если вам действительно не нужно избегать выхода за рамки (что иногда важно, если вы хотите, чтобы другой процесс / программа унаследовала дескриптор файла и могла продолжить чтение с того места, где вы остановились), я бы предложил использовать stdio или ваша собственная система буферизации. Использование и для построчного или побайтного ввода-вывода очень болезненно и трудно сделать правильно.

1
ответ дан 5 December 2019 в 12:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: