К&Р упражнение 1-8. Я могу заставить мой код работать правильно

Я искал, но не нашел решения. Предполагается, что программа считает табуляции, переводы строк и пробелы.

#include <stdio.h>

int main(void)
{
    int c,nl,tab,blank;
    tab = 0;
    blank = 0;
    nl = 0;

    while((c = getchar()) != EOF)
    {
        if(c == '\n');
            nl++;
        if(c == '\t');
            tab++;
        if(c == ' ');
            blank++;
    }

    printf("newline: %d tab: %d blank: %d\n", nl,tab,blank);

    return 0;
}

Когда я запускаю это на FreeBSD, используя ctrl-d для сигнала EOF, каждая переменная отображается с одним и тем же значением. Если я наберу "helloпусто, каквкладкавводитевывводитеctrl-d " он отображает новую строку как 18, вкладку как 18, пустую как 18.

Мой код неправильный? Очевидно, что да, но что не так?


person clawhammer1234    schedule 24.05.2017    source источник
comment
Снимите точку с запятой с конца ваших операторов if, например. if(c == '\n'); -> if(c == '\n'). (Кроме того, это не ошибка как таковая, но научитесь правильно форматировать свой код.)   -  person Paul R    schedule 24.05.2017
comment
спасибо, моя ошибка с форматированием. @PaulR   -  person clawhammer1234    schedule 24.05.2017
comment
При использовании gcc или clang компиляция с предупреждающим флагом -Wall обнаружила бы эту проблему.   -  person M.M    schedule 24.05.2017
comment
@M.M подойдет. Благодарю.   -  person clawhammer1234    schedule 24.05.2017


Ответы (2)


Как сказано в комментарии, проблема здесь в том, что у вас есть точки с запятой после ваших операторов if. Как правило, операторы if заключены в фигурные скобки как таковые:

    if(foo) {
        //your code here
    }

Попробуйте это и посмотрите, работает ли это!

person Austin Hoffmann    schedule 24.05.2017

if (something); буквально означает: если что-то, то ничего не делать. синтаксис оператора if делает так, что точка с запятой в конце преобразует его в нулевое выражение, которое будет выполняться, если условие something истинно, поэтому, если условие указывает, ничего не делается. Когда вы увеличиваете три переменные после операторов if, они будут увеличиваться для каждого символа, который вы читаете из файла, и все они имеют одно и то же значение.

Решение

Просто сотрите ; после правой скобки условия, как в:

if(c == '\n') /* no semicolon here */
        nl++;

В системе FreeBSD:

$ make pru$$
cc -O -pipe  pru24720.c  -o pru24720
$ pru$$ <pru$$.c
newline: 23 tab: 0 blank: 123
person Luis Colorado    schedule 26.05.2017
comment
спасибо, я понятия не имею, что делает ваш make в конце. Я только начинаю с c, так что я думаю, плохо до этого дойдет. И я также начинаю изучать Unix, так что многое сбивает с толку, но я учусь понемногу в день. - person clawhammer1234; 26.05.2017
comment
Что ж, когда я отвечаю здесь на вопрос, я всегда вызываю файл pru$$.c, который заменяет $$ на pid оболочки, поэтому он получает другой номер (и фиксирует весь сеанс оболочки). В этом случае pid оболочки был 24720, так что это было имя файла... наконец, я выполнил pru24720, перенаправив его ввод из файла pru24720.c (исходный код), чтобы получить количество строк кода вашего примера, количество вкладки и количество пробелов. - person Luis Colorado; 26.05.2017
comment
Это встроенная команда unix или это то, что вы написали? - person clawhammer1234; 26.05.2017
comment
@ clawhammer1234, make(1) — это стандартная команда Unix, а замена pid на $$ также является стандартной для оболочки Bourne sh(1) и bash(1). Я написал pru24720.c только для того, чтобы проиллюстрировать свой ответ, и больше ничего. - person Luis Colorado; 28.05.2017