Количество слов, ошибка сегментации - C

Я пытаюсь запустить программу, которая находит количество слов в файле. Каждый раз, когда я компилирую программу, она выдает ошибку сегментации (сброс ядра). Не могу понять, почему.

#include <stdio.h>

int main(int argc, char* argv[]){
    int wc = 1;
    FILE *input = fopen(argv[1],"r");
    char c = fgetc(input);
    while(c != EOF){
        if(c == ' '){
            wc++;
        }
        else
            c = fgetc(input);
    }
    fclose(input);
    printf("Word Count = %d", wc);

return 0;
}

person Charlie Owen    schedule 15.03.2016    source источник
comment
Я компилирую программу, она выдает ошибку сегментации. Я предполагаю, что вы имеете в виду, когда вы запускаете программу. Итак, как вы запускаете программу? Возможно, fopen не удалось. У вас всегда должен быть код проверки ошибок, чтобы убедиться, что вызовы функций выполнены успешно.   -  person kaylum    schedule 16.03.2016
comment
Вы также должны проверить argc, чтобы убедиться, что имя файла было передано в качестве аргумента. Кстати, в первый раз, когда c является пробелом, вы войдете в бесконечный цикл, так как после этого вы никогда не прочитаете новый c. И почему wc устанавливается в 1 до того, как будут найдены какие-либо слова?   -  person lurker    schedule 16.03.2016
comment
char c = fgetc fgetc намеренно возвращает int, а не char. И всегда проверяйте результаты функции на наличие ошибок!   -  person too honest for this site    schedule 16.03.2016
comment
Чтобы расширить комментарий люркера, вы должны использовать while ((c = fgetc(input)) != EOF).   -  person Majora320    schedule 16.03.2016


Ответы (1)


Вы, вероятно, ошибаетесь, потому что не передаете имя файла в командной строке. Когда вы это делаете, argv[1] равно NULL, поэтому fopen разыменовывает указатель NULL.

Вы передаете имя файла своей программе в командной строке следующим образом:

./my_program file_to_test

Чтобы предотвратить создание дампа ядра, вы должны проверить, был ли передан аргумент, проверив значение argc. Вы также должны проверить возвращаемое значение fopen, чтобы убедиться, что файл был открыт:

if (argc < 2) {
    printf("no file name given");
    exit(1);
}
FILE *input = fopen(argv[1],"r");
if (input == NULL) {
    perror("fopen failed");
    exit(1);
}

Тогда у вас другая проблема:

    if(c == ' '){
        wc++;
    }
    else
        c = fgetc(input);

Когда вы находите символ пробела, вы не пытаетесь прочитать следующий символ. Таким образом, c не изменяется после чтения пробела, что приводит к бесконечному циклу.

Вам нужно избавиться от else и всегда вызывать fgetc:

    if(c == ' '){
        wc++;
    }
    c = fgetc(input);

Кроме того, функция fgetc возвращает int (на самом деле unsigned char приводится к int), поэтому вы должны объявить c как int. В противном случае проверка на соответствие EOF может завершиться ошибкой.

person dbush    schedule 15.03.2016
comment
Еще одно: c должно быть int - person Daniel Jour; 16.03.2016