user605947
user605947

Reputation: 119

Segmentation fault (core dumped) read from stdin

I am trying to count the number of each word in a file. The file can be either stdin or a filename provided on the command line(./count -f ). So far the program gives the correct outputs when reading a file from command line. But an error happens when i am trying to read from stdin. The program first output the correct, then give a Segmentation fault (core dumped). Here is part of my code.

    FILE * fp;
int size = 20000;
char sentence[2000]; // the sentence from stdin
if ( argc != 3 ) 
{
    fgets(sentence,sizeof(sentence),stdin); // read from stdin
    fflush(stdin);
    // I think the initialization of word is incorrect, but i do know why it is incorrect
    char *word = strtok (sentence," !\"#$%&'()*+,./:;<=>?@[\\]^_`{|}~\n\t");
    while (word != NULL)
    {
        get_word(word); // get each word
        word = strtok (NULL, " !\"#$%&'()*+,./:;<=>?@[\\]^_`{|}~\n\t");
    }
}
else
{
    fp = fopen( argv[2], "r" );
    if ( fp == 0 )
    {
        printf( "Could not open file\n" );
    }

           char word[1000];
    while (readFile(fp, word, size)) {  // let the program read the file
        get_word(word); // get each word. Works well.
    }
}

get_word function:

void get_word(char *word){
node *ptr = NULL;
node *last = NULL;

if(first == NULL){
    first = add_to_list(word); // add to linked list
    return;
}

ptr = first;
while(ptr != NULL){
    if(strcmp(word, ptr->str) == 0){
        ++ptr->freq;
        return;
    }
    last = ptr;            
    ptr = ptr->next;  
}
last->next = add_to_list(word); // add to linked list

}

Please help me figure out why i get a segmentation fault(core dumped). The program works on my mac, but does not work on Linux.
Thanks in advance.

Upvotes: 1

Views: 2729

Answers (2)

Daniel Fischer
Daniel Fischer

Reputation: 183908

The problem is

int main (int argc, char *argv[]) {
    FILE * fp;

    if ( argc != 3 )
    {
            fgets(sentence,sizeof(sentence),stdin);
            // and so on
    }
    else
    {
            fp = fopen( argv[2], "r" );
            if ( fp == 0 )
            {
                    printf( "Could not open file\n" );
            }
            while (readFile(fp, word, size)) {
                    get_word(word);
            }
    }

    // do some stuff, sorting etc.

    fclose(fp);

that you fclose(fp) regardless of whether it was opened. If fp is not connected to a valid stream, a segmentation fault is common. Apparently some implementations handle a NULL argument to fclose gracefully, and that's what makes it appear to work on Mac.

Move the fclose call into the else branch, and when fopen fails, don't just

printf( "Could not open file\n" );

but end the programme.

Upvotes: 0

user2263253
user2263253

Reputation: 1

sentences size is 2 kib, and you're reading 2 kib from stdin. after that you use a string function on it. strings are ending with an '\0', but since you read 2 kib data without '\0', there is no string-end, so it segfaults, because the string function (strtok in this case) is probably working far beyond 2 kin.

Upvotes: 0

Related Questions