#c #printf
#c #printf
Вопрос:
У меня возникла простая проблема с тем, что printf не печатается, и я не могу понять, является ли код неправильным, или это что-то, что не нравится компилятору, или что-то еще. Для тех из вас, кто знаком с книгой по языку программирования C, это моя попытка решить упражнение 1-8.
#include <stdio.h>
int main() {
int blanks, tabs, newlines;
int c;
blanks = 0;
tabs = 0;
newlines = 0;
while((c = getchar()) != EOF) {
if (c == ' ')
blanks;
if (c == 't')
tabs;
if (c == 'n')
newlines;
}
printf("Blanks: %d n Tabs: %d n Newlines: %d n", blanks, tabs, newlines);
return 0;
}
Кроме того, я использую cc в WSL, если кому-то интересно о настройке
Комментарии:
1. Программа работает, когда я перенаправляю файл в качестве входных данных. Так что же происходит? Вы могли бы попробовать
fflush(stdout);
послеprintf
. Каков был ваш вклад?2. Как вы его запускаете?
3. Вам нужно ввести файл, потому что вы используете
EOF
4. Вы также можете вводить данные с клавиатуры, завершая его с помощью Ctrl-D (Linux) или Ctrl-Z (Windows).
5. О, я просто набирал его и нажимал enter, теперь он работает с ctrl D, спасибо!
Ответ №1:
getchar
среди других функций, связанных с stdin, считывает данные со стандартного ввода. Как и большинство вещей в C, это синхронный (или, точнее, «блокирующий») вызов, означающий, что он будет ждать, пока что-то прочитается.
В отличие от библиотек более высокого уровня, с которыми вы можете быть знакомы (например, в Python), C не поставляется с набором функций управления потоком.
Вместо этого, когда вы читаете из stdin, вам нужно на самом деле предоставить ему что-то, иначе у вызова getchar
не будет другого выбора, кроме как ждать чего-то.
Ваша оболочка (bash, sh, fish, zsh, cmd.exe , что угодно) принял решение разрешить ручной ввод текста (через TTY), вместо того, чтобы закрывать stdin и вызывать сбой программы. Вот почему ваша программа зависает на неопределенный срок — она ждет, когда вы что-нибудь сделаете, поскольку вы не предоставили оболочке ничего для передачи в stdin вместо этого.
Общепринятым (хотя и не единственным) способом сигнализации EOF в этом интерактивном режиме является Ctrl-D (в некоторых системах Ctrl-Z — это последовательность EOF). Это говорит оболочке указать EOF программе, которая в данный момент использует стандартный идентификатор, и, таким образом, ваша программа получит TRUE (1)
для сравнения с EOF (или FALSE (0)
в данном случае, поскольку вы отрицали его с !=
помощью ).
Следовательно, почему он зависает. Ваш код еще даже не дошел до инструкции printf 🙂