简体   繁体   中英

read file line by line in C(without using fgets)

I have a file with 3 lines in it, I'm tring to read this file and save each line as a separate string. here is what I tried to do, it does save the first line but it overrides it by saving the first line and the second line' and I can't get my head around on how to do save each line as an individual string , and also I'm getting an error->

* stack smashing detected * : /home/ubuntu/workspace/ex12.co terminated Aborted

 #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;        
}

NOTE: I DO NOT WANT to use fopen,fgets,sscanf or getline. Any help would be appreciated

printf prints until a NULL terminating character is seen. Your printf goes over unallocated memory areas because you are not inserting a NULL(value 0) at the end of the string. Also, you forgot to reinitialize i to 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);
    }
}

The reason you are getting the error is most likely because you never reset i back to 0 so you keep reading more than 80 characters in to firstline

As to saving each line in to its own string, your just need to use you other variables, instead of using firstline all the time.

There a couple of ways to do that:

  1. When you detect end of line exit the loop (with break ), and start another loop where you will put the characters in secondline . Do the same for third.

  2. If you already learned a bit about pointers, you can keep one loop, but use an extra variable, like char *currentLine that will hold the address of the array you want to read in to. Change the address every time you detect end of line like this: currentLine = secondline .

Also remember to put '\\0' at the end of every line you read, or your program may print garbage when you try to print what you read to the screen.

the following proposed code:

  1. cleanly compiles
  2. performs the desired functionality
  3. proper checks for and handles errors
  4. gives 'magic' numbers (3, 80) meaningful names

and now, the proposed code:

#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;        
}

Note: this code assumes that each line is less than 80 characters

running the proposed code against its' own source file results in:

#include <stdio.h>

#include <stdlib.h>

#include <sys/types.h>

Here is an example to demonstrate the brake from first loop from your example:

#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);
}
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM