【问题标题】:Printing the first 10 lines of a file in C with open() and read()使用 open() 和 read() 在 C 中打印文件的前 10 行
【发布时间】:2021-12-19 17:34:36
【问题描述】:

我正在尝试使用函数 open() 和 read() 打印 txt 文件的前 10 行。到目前为止,我已经设法打印了整个文件,但是当我到达第 10 行的末尾时,我遇到了停止代码的问题。我该怎么办?

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>

int main(){
    int fd = open("a.txt", O_RDONLY);
    if(fd < 0){
        printf("Error: %d\n", errno);
        perror("");
    }

    char *c = (char*)calloc(100, sizeof(char));
    ssize_t res;
    int max = 0;

    while(res = read(fd, c, 1) && max < 10){
        if(res < 0){
            printf("Error: %d\n", errno);
            perror("");
        }

        c[res] = '\0';
        if(c[res] == '\n'){
            max++;

        }
        printf("%s", c);

    }

    close(fd);
    return 0;
}

【问题讨论】:

  • 简短的回答是使用流和面向行的输入函数,如fopen()fgets()
  • 在该行中: if(c[res] == '\n'){ c[res] 永远不会是 '\n' 因为你刚刚在上一行中设置了 '\0' .
  • @SergioJ.Batarce 更不用说如果res 是读取的字节数,那么c[res] 是该数据之外的一个字节;读取的字节是c[0]c[res-1]。哈哈。

标签: c file


【解决方案1】:

以下总是将位置res设置为'\0',然后立即检查是否为'\n'

c[res] = '\0';
if(c[res] == '\n'){
    max++;
}

这永远不会成立。因此,max 永远不会增加,您将阅读整个文件。

此外,res 保存read(fd, c, 1) &amp;&amp; max &lt; 10 的结果。它需要括号将分配隔离到正确的结果:(res = read(fd, c, 1)) &amp;&amp; max &lt; 10(尽管切换这些顺序将有助于避免不必要的读取)。

如果您一次读取一个字节的文件,则无需分配如此大的缓冲区。一个字节的存储空间就足够了。您可以使用"%c" 来打印单个字符(或使用write),而不是使用"%s" 来打印以NUL 结尾的字符串。

使用readwrite 的示例:

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

int main(void) {
    char byte;
    int newlines = 0;
    int fd = open("a.txt", O_RDONLY);
                                    
    while (newlines < 10 && read(fd, &byte, 1) > 0) {
        /* alternatively: printf("%c", byte); */
        write(STDOUT_FILENO, &byte, 1);

        if (byte == '\n')
            newlines++;
    }

    close(fd);
}

【讨论】:

  • 谢谢,它运行良好。我仍在学习如何使用 open()、read() 和所有其他函数,所以我有一半时间不知道自己在做什么。你帮了大忙。
猜你喜欢
  • 2020-06-26
  • 2016-09-02
  • 2021-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-03
  • 1970-01-01
  • 2011-09-16
相关资源
最近更新 更多