Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Подсчет символов


Автор: alnight 18.11.2013, 23:47
Вопрос по коду из книги Кернигана и Ритчи.
Код программы подсчета символов:
Код

 #include <stdio.h> 
/* подсчет символов во входном потоке; 1-я версия */ 
main() 
{ 
     long nc; 
     nc= 0 ; 
     while (getchar() != EOF) 
          ++nc; 
     printf("%ld\n", nc); 
}      


Все работает хорошо, если входные данные такие:
Код

qwe
^Z
4

Все хорошо, 4 символа в 1 строке, символ EOF не считается, допустим.
Но если я ввожу вот такие данные:
Код

qwe^Zqwe
^Z
4

То мало того, что, оказывается, программа не реагирует на EOF не с начала строки, так еще и не считает после ^Z символы в строке. НО! Игнорирует лишь простые символы, а вот перевод строки, которая идет после ^Z в 1 строке все равно подсчитывается.
Поэтому воникает 2 вопроса:
1) почему программа не реагирует на ^Z не в начале строки?
2) раз уж не раегирует и не считает символы после ^Z, почему все-таки считается переход на новую строку?

Автор: baldina 19.11.2013, 00:11
особенности - в устройстве консоли: символы пересылаются в программу построчно, т.е. не по мере ввода, а после перевода строки. при вводе из файла, например, такого эффекта не будет (можно проверить, не меняя программу, если перенаправить стандартный ввод при помощи '<')

Добавлено через 12 минут и 54 секунды
поиграться с консолью windows и понаблюдать как интерпретируется ввод можно вызвав командный интерпретатор cmd.exe и выполнив в нем команду copy con: con:
все вводимое с консоли будет выводиться на консоль

Автор: alnight 19.11.2013, 00:42
Построчно, но разве программа не разбирает строку посимвольно, чтобы определить, что же там за символ? Почему она видит EOF только в начале и игнорирует в середине?

Автор: baldina 19.11.2013, 02:01
программа разбирает посимвольно, но ОС передаёт символы не в момент нажатия на клавишу, а после Enter. Это особенность драйвера консоли, и к работе программы по сути не относится.
а в середине не должно игнорировать, ошибся походу.. copy con: con: выводит до первого ^Z, неважно где он.
впрочем, может быть ваша консоль работает чуть иначе))
пять копеек про К&R: это, конечно, классика, но некоторые объяснения могут оказаться несколько устаревшими старомодными

Добавлено через 5 минут и 31 секунду
что бы не зависеть от разных эффектов предлагаю http://ideone.com/YuidVk потренироваться. здесь есть окошко для ввода содержимого, отправляемого с консоли. ^Z там не нужен, конец файла - конец данных

Автор: alnight 19.11.2013, 23:36
Цитата

что бы не зависеть от разных эффектов предлагаю тут потренироваться. здесь есть окошко для ввода содержимого, отправляемого с консоли. ^Z там не нужен, конец файла - конец данных


Спасибо за ссылку, только там все равно не поставить EOF в середину.
Я отрабатывал на консоли 8 винды.
Сейчас специально попробовал в никсах скопилировать с помощью gcc и запустить на терминале. Там немного иначе получилось: не высвечивается ничего когда ввожу ^D, в середине строки никак не реагирует, но если нажать дважды - реагирует, причем правильно.

Почему в винде символ EOF из середины строки не обрабатывается?
Возник и другой вопрос =) Почему в unix обрабатывается так странно?

Автор: baldina 20.11.2013, 00:17
alnight, как-то до вас медленно доходит.
если вас интересуют особенности работы в консоли разных ОС, задавайте вопрос об этом. к вашей программе это не имеет ровно никакого отношения. программа правильная и работает верно.
если вас интересует обработка нажатия клавиш, это другая тема, решается средствами ОС или сторонних библиотек.

Добавлено через 50 секунд
Цитата(baldina @  20.11.2013,  00:17 Найти цитируемый пост)
задавайте вопрос об этом

в соответствующем разделе, а не С/С++

Автор: alnight 20.11.2013, 00:41
В целом примерно понятно.
Что программа работает правильно я догадывался, она ведь из учебника =)
Пытаюсь разобраться в нюансах языка и работы скопмилированного кода с вопросом "а почему именно так".
Спасибо за разъяснения.

Автор: baldina 20.11.2013, 01:05
"скопмилированный код" не в вакууме находится. программист должен иметь хотя бы общие понятия об устройстве ОС, файловом вводе-выводе, работе пользователя в ОС.

представьте, вы разработали самокат и решили его протестировать на дорогах общего пользования. но ПДД вы не знаете. соседи по потоку вам сигналят, т.к. ваши действия с их точки зрения (и ПДД) неадекватны. вы понимаете, что что-то не так, и начинаете задавать вопросы. но ПДД вы не знаете, поэтому выдаете следствия за причины, и вопросы в стиле "почему самокат так странно едет".

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)