【问题标题】:How to read line by line using system call in C如何使用C中的系统调用逐行读取
【发布时间】:2019-12-29 19:00:13
【问题描述】:

在我的程序中,我目前可以逐字符读取具有给定名称“fichier1.txt”的文件,但我正在寻找的是存储一行(此处为行字符指针),然后以这种方式显示:

-ligne 1 : 内容行 1

-line 2 : 内容第 2 行

-等等...

我尝试按字符存储字符,但由于它是一个指针,而且我对指针非常熟悉,所以我无法存储一行,然后重用指针来存储下一行的字符。

我不得不说它是学校项目的一部分,我必须使用 POSIX 标准。

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

int main(){
    int read_fd, write_fd;
    off_t offset = 0;
    char lu;
    struct stat statFd;
    char *fichier = "fichier1.txt";


    read_fd = open(fichier,O_RDONLY);
    stat(fichier, &statFd);

    if(read_fd == -1){
        perror("open");
        exit(EXIT_FAILURE);
    }

    int i = 0;
    char * line; // variable to store line

    while(lseek(read_fd,offset, SEEK_SET) < statFd.st_size)
    {
        if(read(read_fd, &lu, 1) != -1)
        {
            printf("%c",lu);
            offset++;

        } else {
            perror("READ\n");
            close(read_fd);
            close(write_fd);
            exit(EXIT_FAILURE);
        }
    }

    return 0;
}



我想使用 open() 函数而不是 fopen()

【问题讨论】:

  • 不要包含你能想到的每一个标题——只包含你需要的那些。
  • 打开文件后,您可以使用 fstat 获取统计信息,从而避免再次打开文件和某些竞争条件。

标签: c linux io posix system-calls


【解决方案1】:

由于您可以从文件中读取一个又一个字符,while 循环中的逻辑将用于一次将整行(最多 199 个字符,您可以增加它)存储在一个数组中 & 然后显示它:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>



int main(void)
{
    FILE *fptr=fopen( "fichier1.txt","r");
    int  i;
    char arr[200];     //THIS ARRAY WILL HOLD THE CONTENTS OF A LINE TEMPORARILY UNTIL IT IS PRINTED                       
    int temp_index=0,line_number=1;;
    memset(arr,'\0',sizeof(arr));

    while((i=getc(fptr))!=EOF)                         
    {
        if(i!='\n')                                
        {
            arr[temp_index++]=i; 
        }   
        if(i=='\n')
        {
            printf(line %d: %s\n",line_number++,arr);
            temp_index=0;
            memset(arr,'\0',sizeof(arr));
        } 
    }
    return 0;
}

【讨论】:

    【解决方案2】:

    在每次迭代中调用lseek 可能效率低下,并且可能在无法搜索的设备上失败。如果我不需要存储线,我会按照下面的这些线编写一个程序。

    #include <stdio.h>
    #include <stdlib.h>
    
    int main (void)
    {
        int lc = 0; /* line count */
        int c;      /* character read */
    
        FILE *fp = fopen("fichier1.txt", "r");
        if (fp == NULL) {
            perror("fopen");
            return EXIT_FAILURE;
        }
    
        while ((c = fgetc(fp)) != EOF) {
            printf("line %d: ", ++lc);
            while (c != '\n' && c != EOF) {
                putchar(c);
                c = fgetc(fp);
            }
            putchar('\n');
        }
    
        return 0;
    }
    

    或者,使用fgets 一次读取一行的程序:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <stdbool.h>
    
    int main (void)
    {
        int lc = 0; /* line count */
        char buf[4096]; /* buffer to store the line read */
        bool newline = true;
    
        FILE *fp = fopen("fichier1.txt", "r");
        if (fp == NULL) {
            perror("fopen");
            return EXIT_FAILURE;
        }
    
        while (fgets(buf, sizeof buf, fp) != NULL) {
            if (newline)
                    printf("line %d: ", ++lc);
            printf("%s", buf);
            newline = strchr(buf, '\n');
        }
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-14
      • 1970-01-01
      • 2014-08-22
      • 2019-03-22
      • 1970-01-01
      相关资源
      最近更新 更多