从stdin读取分段错误(核心转储)

时间:2013-04-09 19:05:31

标签: c segmentation-fault

我正在尝试计算文件中每个单词的数量。该文件可以是stdin或命令行上提供的文件名(./ count -f)。到目前为止,程序在从命令行读取文件时提供正确的输出。但是当我尝试从stdin读取时会发生错误。程序首先输出正确的,然后给出Segmentation故障(core dumped)。这是我的代码的一部分。

    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函数:

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

}

请帮我弄清楚为什么会出现分段错误(核心转储)。 该程序在我的Mac上运行,但在Linux上不起作用 提前谢谢。

2 个答案:

答案 0 :(得分:0)

句子大小为2 kib,你正在从stdin读取2 kib。之后你在它上面使用一个字符串函数。字符串以'\ 0'结尾,但由于你读了没有'\ 0'的2个kib数据,所以没有字符串结尾,所以它是段错误的,因为字符串函数(在这种情况下是strtok)可能远远超过2亲属。

答案 1 :(得分:0)

问题是

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);

fclose(fp)无论是否被打开。如果fp未连接到有效流,则分段错误很常见。显然,有些实现会优雅地处理NULLfclose的{​​{1}}参数,这就是它在Mac上运行的原因。

fclose调用移至else分支,当fopen失败时,不要只是

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

但结束了该计划。