Search code examples
cgetlinestrtok

Why is my getline() not reading the first line of my standard input in C?


I'm relatively new to C, and I am uing the getline() function to read the contents of a file supplied as standard input.

However, the while loop does not read the first line of the file & I'm not sure why!

For context: the file reads-

a b c
-d e 
f

And the output reads & splits -d, e & f correctly, but only prints the a b c outside the while loop.

int main (){

//utilising data provided at http://www.linux.die.net/man/3/getline
//char*linePointer is initialized to NULL, for getline() to allocate a buffer that stores the line
//buffer gets resized dynamically 

char *linePointer = NULL; 
size_t len = 0;

//checks if the file is empty and prints -, if it is
if ((getline(&linePointer, &len, stdin) == -1)){
    printf("-\n");
}

//as long as the stream is valid, and the file can be read 
//if either of the conditions are not satisfied then while loop condition is not satisfied 
//prints the contents of the line 

Clauses cs = createNewArrayList();
printf("%s\n", linePointer);
while ((getline(&linePointer, &len, stdin) != -1)){
        printf("%s\n", linePointer);

    Clause c = createNewArrayList();
    char *token; 
    char *delim = " ";
    token = strtok(linePointer, delim);
    while (token != NULL){      
        char *duplicate = strdup(token);     
        add(c, duplicate);
        printf("%s\n",duplicate);
        token = strtok(NULL, delim);
    }
    add(cs, c);
}

free(linePointer);
exit(EXIT_SUCCESS);    

Solution

  • You are reading and discarding the 1st line before entering your while loop, that is why the loop does not see that line.

    Try this instead:

    int main (){
    
        //utilising data provided at http://www.linux.die.net/man/3/getline
        //char*linePointer is initialized to NULL, for getline() to allocate a buffer that stores the line
        //buffer gets resized dynamically 
    
        char *linePointer = NULL; 
        size_t len = 0;
    
        //checks if the file is empty and prints -, if it is
        if ((getline(&linePointer, &len, stdin) == -1)){
            printf("-\n");
        }
        else{
            //as long as the stream is valid, and the file can be read 
            //if either of the conditions are not satisfied then while loop condition is not satisfied 
            //prints the contents of the line 
    
            Clauses cs = createNewArrayList();
            do{
                printf("%s\n", linePointer);
    
                Clause c = createNewArrayList();
                char *delim = " ";
                char *token = strtok(linePointer, delim);
                while (token != NULL){      
                    char *duplicate = strdup(token);     
                    add(c, duplicate);
                    printf("%s\n",duplicate);
                    //if add() makes its own copy, then uncomment this,
                    //or simply don't use strdup() above to begin with:
                    //free(duplicate);
                    token = strtok(NULL, delim);
                }
                add(cs, c);
    
                free(linePointer);
                linePointer = NULL; 
                len = 0;
            }
            while (getline(&linePointer, &len, stdin) != -1);
        }
    
        free(linePointer);
        exit(EXIT_SUCCESS);
    }