Reputation: 119
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
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
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