首页 文章

在C中逐行读取文件(不使用fgets)

提问于
浏览
0

我有一个包含3行的文件,我想读取这个文件并将每行保存为一个单独的字符串 . 这是我试图做的,它确实保存了第一行,但它通过保存第一行和第二行来覆盖它而且我无法理解如何将每行保存为单独的字符串,并且我也得到一个错误 - >

堆栈粉碎检测:/ home /ubuntu / workspace / ex12.c.o终止中止

#include <stdio.h>
 #include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include<stdio.h> 
 #include<fcntl.h> 
 #include<errno.h> 
 #include <unistd.h>
 extern int errno;                               
int main( int argc, char *argv[] )  {
    char *path1;   
    char  firstline[80];
    char  secondline[80];
    char  thirdline[80];  

    printf("Program name %s\n", argv[0]);

    if( argc == 2 ) {
         printf("The path of the config file that you supplied is %s\n", argv[1]);
    }
    else if( argc > 2 ) {
        printf("Too many arguments supplied.\n");
    }
    else {
        printf("One argument expected.\n");
    }

    int fd1 = open(argv[1], O_RDONLY | O_CREAT);  

    if (fd1 ==-1) 
    { 
        // print which type of error have in a code 
        printf("Error Number % d\n", errno);  

        // print program detail "Success or failure" 
        perror("Program"); 
        exit(EXIT_FAILURE);
    }       
    else {            
        char c;
        int i=0;            

        while ((read(fd1, &c, 1) == 1) )
        {                
            firstline[i++]=c;                
            if(c=='\n')
            {
                //printf("end of line"); 
                printf("%s",firstline);
            }

        }
    }
    int close(int fd1);         
    return 0;        
}

注意:我不想使用fopen,fgets,sscanf或getline . 任何帮助,将不胜感激

4 回答

  • 0

    printf 打印,直到看到NULL终止字符 . 您的printf遍历未分配的内存区域,因为您没有在字符串的末尾插入NULL(值0) . 此外,您忘了将i重新初始化为0 .

    while ((read(fd1, &c, 1) == 1) )
    {                
        firstline[i++]=c;                
        if(c=='\n')
        {
            firstline[i] = 0;
            i = 0;
            //printf("end of line"); 
            printf("%s",firstline);
        }
    }
    
  • 0

    您收到错误的原因很可能是因为您从未将 i 重置为0,因此您继续读取超过80个字符到 firstline

    至于将每一行保存到自己的字符串中,您只需要使用其他变量,而不是始终使用_60209 .

    有几种方法可以做到这一点:

    • 当您检测到行尾退出循环(使用 break ),并启动另一个循环,您将把字符放在 secondline 中 . 为第三个做同样的事 .

    • 如果你已经学过一些关于指针的知识,你可以保留一个循环,但是使用一个额外的变量,比如 char *currentLine ,它将保存你想要读入的数组的地址 . 每次检测到行尾时都要更改地址,如下所示: currentLine = secondline .

    还记得在你阅读的每一行的末尾加上'\ 0',或者当你试图将你读到的内容打印到屏幕上时,你的程序可能会打印出垃圾 .

  • 0

    以下提议的代码:

    • 干净地编译

    • 执行所需的功能

    • 正确检查并处理错误

    • 给出'magic'个数字(3,80)有意义的名字

    现在,建议的代码:

    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <fcntl.h>
    #include <errno.h>
    #include <unistd.h>
    
    #define MAX_LINES 3
    #define MAX_LINE_LEN 80
    
    
    int main( int argc, char *argv[] )  
    {
        char Lines[ MAX_LINES ][ MAX_LINE_LEN ] = { '\0' };
    
    
        if( argc != 2 )
        {
            fprintf( stderr, "USAGE: %s <configFileName>\n", argv[0] );
            exit( EXIT_FAILURE );
        }
    
        // implied else, correct number of command line arguments
    
    
        int fd1 = open(argv[1], O_RDONLY );  
    
        if (fd1 ==-1) 
        { 
            perror( "open failed" ); 
            exit(EXIT_FAILURE);
        }  
    
        // implied else, open successful        
    
        char c;
    
        for( int i = 0; i < MAX_LINES; i++ )
        {
            for( int j=0; j< MAX_LINE_LEN; j++ )
            {
                ssize_t bytecount = read(fd1, &c, 1 );
                if( bytecount < 0 )
                {
                    perror( "read failed" );
                    close( fd1 );
                    exit( EXIT_FAILURE );
                }
    
                // implied else, read successful 
    
                Lines[ i ][ j ] = c;
    
                if( c == '\n' )
                {
                    break;
                }   
            } 
        }
    
        for( int i = 0; i< MAX_LINES; i++ )
        {
            printf( "%s\n", Lines[i] );
        }
    
        close( fd1 );         
        return 0;        
    }
    

    注意:此代码假定每行少于80个字符

    针对其自己的源文件运行建议的代码会导致:

    #include <stdio.h>
    
    #include <stdlib.h>
    
    #include <sys/types.h>
    
  • 0

    这是一个示例,用于演示来自示例的第一个循环的制动:

    #define MAXLENGTH 80    
    ...
    
    char  firstline[MAXLENGTH + 1] = {0};
    char  secondline[MAXLENGTH + 1] = {0};
    char  thirdline[MAXLENGTH + 1] = {0};  
    ....
    else {            
        char c;
        int i=0;            
        while ((read(fd1, &c, 1) == 1 && i < MAXLENGTH)
        {                
            firstline[i++]=c;                
            if(c=='\n')
            {
                break; /* break from first loop */
            }
        }
        /* add a '\0' to the end of the string! */
        firstline[i] = '\0';
        //printf("end of line"); 
        printf("%s",firstline);
        i=0;            
        while ((read(fd1, &c, 1) == 1 && i < MAXLENGTH)
        {                
            secondline[i++]=c;                
            if(c=='\n')
            {
                break; /* break from second loop */
            }
        }
        /* add a '\0' to the end of the string! */
        secondline[i] = '\0';
        printf("%s",secondline);
        i = 0;
        int i=0;            
        while ((read(fd1, &c, 1) == 1 && i < MAXLENGTH)
        {                
            thirdline[i++]=c;                
            if(c=='\n')
            {
                break; /* break from third loop */
            }
        }
        /* add a '\0' to the end of the string! */
        thirdline[i] = '\0';
        //printf("end of line"); 
        printf("%s",thirdline);
    }
    ...
    

相关问题