2010-02-27 149 views
8

我需要做的是使用unistd.h中的read函数逐行读取文件 。我有这样的时刻:unistd.h read()函数:如何逐行读取文件?

n = read(fd, str, size); 

然而,这读取到该文件的末尾,或最多字节大小数。 有没有办法让我一次读一行,停在换行符上? 这些线条都是可变长度的。

我只允许这两个头文件:

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

的练习的要点是通过文件里逐行读取,并 输出的每一行,因为它的读取基本上以模仿fgets() 和fputs()函数。

+0

您将需要使用'write()'来模拟'fputs()' - 你不能这样做:) – 2010-02-27 20:30:09

回答

8

您可以逐字符读入缓冲区并检查换行符号(适用于Windows的\r\n和适用于Unix系统的\n)。

0

这是一个很好的问题,但只允许读取功能并没有帮助! :P

循环读取调用以获取固定数量的字节并搜索'\ n'字符,然后返回字符串的一部分(直到'\ n'),并将其余部分(除\ n ')预先添加到下一个字符文件块。

使用动态内存。

更大的缓冲区,更少的读取调用(这是一个系统调用,所以不便宜,但现在有先发制人的内核)。

...

或者简单修复的最大行长度,并用fgets,如果你需要快速...

0

如果您打开文本模式,那么Windows“文件\ r \当文件被读取时,n将被默默地转换为“\ n”。

如果你在Unix上,你可以使用非标准的gcc'getline()'功能。


getline()功能是在2008年POSIX

+3

OP希望从文件描述符而不是FILE流中读取数据。 getline()从文件流中读取,并且需要,这是不允许的。 – SzG 2013-10-06 18:06:42

0

嗯标准,它将从一个终端读取线由行。

你有一些选择是:

  • 编写使用读取功能,当它运行的数据,但一次只能返回一行给调用者
  • 使用中,做库中的函数完全如此:fgets()
  • 一次只能读取一个字节,所以你不要太过分。
1

不幸的是,读取功能并不适合这种输入。假设这是来自面试/家庭作业/练习的某种人为要求,您可以尝试模拟基于行的输入,方法是通过分块读取文件并自行将其分割为换行符,并在调用之间以某种方式维护状态。如果仔细记录功能的使用情况,您可以使用静态位置指示器。

4

你会想要创建一个缓冲区长度的两倍,你会支持你最长的行,你需要跟踪你的缓冲区状态。

基本上,每次你被要求换新行时,你都会从你当前的缓冲区位置开始扫描,寻找一个行尾标记。如果你找到一个,那好,那是你的路线。更新你的缓冲区指针并返回。

如果你打你的maxlength,那么你返回一个截断的行并将你的状态改为放弃。下次打电话时,您需要放弃直到下一行,然后输入正常的读取状态。

如果您打开所读内容的结尾,则需要读入另一个maxline字符,如果触到底部,则打包到缓冲区的开头(即,您可能需要进行两次读取调用)然后继续扫描。

以上全部假设您可以设置最大线路长度。如果你不能那么你必须使用动态内存,并担心如果一个缓冲区malloc失败会发生什么。另外,如果您在读入缓冲区时碰到文件末尾,则需要始终检查读取结果。

1

如果您需要使用read()精确读取1行(而不是超范围),唯一通用的方法是每次读取1个字节并循环,直到获得换行字节。但是,如果您的文件描述符指向一个终端,并且它处于默认(规范)模式,则读取将等待换行符,并且只要有一行可用,就会返回小于所请求的大小。但是,如果数据很快到达,它可能会返回多行,或者如果程序的缓冲区或内部终端缓冲区比行长度短,则可能返回的行少于1行。除非你真的需要避免超越(这有时很重要,如果你希望另一个进程/程序继承文件描述符,并能够从你离开的地方继续阅读),我会建议使用stdio函数或你的拥有自己的缓冲系统。对于基于行或逐字节的IO,使用read非常痛苦,很难正确使用。