Второй шаг в программировании на С (недоумение прямо какое-то...)
Модератор: Модераторы разделов
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Второй шаг в программировании на С
#include <stdio.h>
main ()
{
int c;
c= getchar();
while (c!= EOF) {
putchar (с);
c= getchar ();
}
}
Это программа из учебника. Её суть: набрал текст, нажал "Enter", тект скопировался. Но! Для текста, оказывается, должны быть такие ограничения (не оговорённые): любая из его строк кроме конечной должна быть по длине не меньше того количества символов, которое влезает по ширине в терминал. Если она будет меньше, в конце её нажимаем "Enter". Всё, текст на этом прервался и скопировался. А символ конца строки если писать (\n), то он тоже просто копируется как \n. Функциональной нагрузки т.е. не несёт.
Вопрос-то состоит, собственно говоря, в уточнении вышеизложенного факта. Я бы не стал его задавать, но вот эта фраза из учебника ввела меня в заблуждение: "Простейшим примером является программа, копирующая входной поток в выходной по одному символу". По факту же она копирует только до... Впрочем, я уже об этом писал.
Спасибо.
main ()
{
int c;
c= getchar();
while (c!= EOF) {
putchar (с);
c= getchar ();
}
}
Это программа из учебника. Её суть: набрал текст, нажал "Enter", тект скопировался. Но! Для текста, оказывается, должны быть такие ограничения (не оговорённые): любая из его строк кроме конечной должна быть по длине не меньше того количества символов, которое влезает по ширине в терминал. Если она будет меньше, в конце её нажимаем "Enter". Всё, текст на этом прервался и скопировался. А символ конца строки если писать (\n), то он тоже просто копируется как \n. Функциональной нагрузки т.е. не несёт.
Вопрос-то состоит, собственно говоря, в уточнении вышеизложенного факта. Я бы не стал его задавать, но вот эта фраза из учебника ввела меня в заблуждение: "Простейшим примером является программа, копирующая входной поток в выходной по одному символу". По факту же она копирует только до... Впрочем, я уже об этом писал.
Спасибо.
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 2910
Re: Второй шаг в программировании на С
Знаю эту книгу, там оч хорошо все написано, читай внимательнее. \n - это последовательность только внутри программы.
-
- Сообщения: 436
- Статус: Интересующийся новичок
- ОС: Debian GNU/Linux 4 & 5
Re: Второй шаг в программировании на С
promov писал(а): ↑03.09.2007 11:18while (c!= EOF) {
в конце её нажимаем "Enter". Всё, текст на этом прервался и скопировался. А символ конца строки если писать (\n), то он тоже просто копируется как \n. Функциональной нагрузки т.е. не несёт.
"Простейшим примером является программа, копирующая входной поток в выходной по одному символу". По факту же она копирует только до... Впрочем, я уже об этом писал.
Спасибо.
Ничего подобного.
Внимательнее надо быть.
После нажатия "Энтер" набираем символы дальше. Нажимаем энтер. И так пока не надоест.
Когда надоест - вводим ЕОф (контрол + D). Или зачем по-вашему там в коде EOF болтается?
Последовательность \n в потоке символов естественно представляет два символа. В один символ ньюлайн она превращается только там, где система обработки ввода это предполагает. В символьных и строковых литералах Си - в частности.
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Второй шаг в программировании на С
Я знал, что мне опять не повезёт. То ли клавиатура такая, то ли Linux...
...При нажатии на "Enter" ввод прекращается и выводится только что набранная строка...
Есть какой-нибудь совет?
...При нажатии на "Enter" ввод прекращается и выводится только что набранная строка...
Есть какой-нибудь совет?
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 436
- Статус: Интересующийся новичок
- ОС: Debian GNU/Linux 4 & 5
Re: Второй шаг в программировании на С
Есть. Прочитать то, что я написал чуть выше. Учиться не только задавать вопросы, но и читать ответы.
Если совсем нечем заняться - попробуйте то же собрать в виндозе. И клавиатуру другую подключите.
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Второй шаг в программировании на С
Да вы поймите, у меня после нажатия на "Enter", написанное сразу же воспроизводится ещё раз (я ведь писал об этом), а из ваших слов я понимаю, что просто курсор должен на другую строчку переходить. Вы мне просто скажите, правильно то, что у меня происходит или нет. А то может, это и есть то самое пресловутое копирование (в чём я сильно сомневаюсь), а я тут огород горожу.
Зря вы так.
И так, между прочим, изинтереса: где мне прочитать информацию о том, что "сtrl+d" и есть то самое EOF? В хвалёной всеми книжке Кернигана и Ричи, которуюя штутдирую этого нет... Может, в конце разве что? Так я книги с начала читаю...
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 614
Re: Второй шаг в программировании на С
EOF - End Of File
http://ru.wikipedia.org/wiki/EOF
http://en.wikipedia.org/wiki/End-of-file
Я не понимаю Вашего вопроса

Фишка в том, что терминалы имеют разный режим работы.
По умолчанию getchar() заканчивает ввод после энтера.
хотя можно настроить терминал таким образом, что бы getchar() возвращал значение после каждого нажатия клавиши.
Также по умолчанию терминал отображает введенные на него клавиши сам, а после того как Вы жмете энтер, введенные Вами символы, повторно выводятся на экран Вашей программой.
Гуд?
PS Таки сколько Вам лет, если не секрет. За сорок?

-
- Сообщения: 3339
- ОС: Slackware 12.2, ArchLinux 64
Re: Второй шаг в программировании на С
Скомпилировал указанную программу, попробовал прогнать в xterm'е и в консоли. В обоих случаях поведение такое, как ожидается.
В каком терминале это не работает? В каком дистре?
Код: Выделить всё
teddy@laptop~$ testproggie
gshasgjsgHJASG
gshasgjsgHJASG
yeuwyeuwyeuwyeuwye hhjhjad
yeuwyeuwyeuwyeuwye hhjhjad
ywueuwye
ywueuwye
<--- тут я нажимаю Ctrl+D и прога выходит -->
teddy@laptop~$
В каком терминале это не работает? В каком дистре?
-
- Сообщения: 636
- ОС: Debian GNU/Linux
Re: Второй шаг в программировании на С
Всё очень просто.
Предположим вы вводите строку "abc<enter>" <enter> это энтер, а не строка из 7 знаков
когда вы на клавиатуре нажимаете a, драйвер клавиатуры говорит об этом терминалу, который печатает a, и сохраняет a во внутреннем буфере драйвера.
То же происходит при b и c, таким образом сейчас во внутреннем буфере драйвера три буквы a b c.
Обратите внимание - всё это время ваша программа "висела" в первом вызове getchar, и операционная система ей ещё никаких данных не посылала.
Теперь вы нажимете <enter>
Драйвер клавиатуры посылает это терминалу, и он переводит курсор на новую строку.
Так же ОС посылает вашей программе по очереди символы a, b, c, <newline>, где <newline> это либо символ с кодом 10, либо символ с кодом 13, либо пара этих символов - в зависимости от ОС. В линуксе это всегда символ с кодом 10. Именно этот символ в программе пишется как '\n'
теперь ваша программа 4 раза получает эти символы и тут же печатает их.
получается строка abc и перевод строки.
Предположим вы вводите строку "abc<enter>" <enter> это энтер, а не строка из 7 знаков

когда вы на клавиатуре нажимаете a, драйвер клавиатуры говорит об этом терминалу, который печатает a, и сохраняет a во внутреннем буфере драйвера.
То же происходит при b и c, таким образом сейчас во внутреннем буфере драйвера три буквы a b c.
Обратите внимание - всё это время ваша программа "висела" в первом вызове getchar, и операционная система ей ещё никаких данных не посылала.
Теперь вы нажимете <enter>
Драйвер клавиатуры посылает это терминалу, и он переводит курсор на новую строку.
Так же ОС посылает вашей программе по очереди символы a, b, c, <newline>, где <newline> это либо символ с кодом 10, либо символ с кодом 13, либо пара этих символов - в зависимости от ОС. В линуксе это всегда символ с кодом 10. Именно этот символ в программе пишется как '\n'
теперь ваша программа 4 раза получает эти символы и тут же печатает их.
получается строка abc и перевод строки.
-
- Сообщения: 436
- Статус: Интересующийся новичок
- ОС: Debian GNU/Linux 4 & 5
Re: Второй шаг в программировании на С
Да не, проблема в том, что человек не понимает, почему прога что-то выводит, когда он думает, что еще не все ввел.
Запустите ее с перенаправлением вывода:
1). И дальше вводите что хотите, и нажимайте ентер сколько угодно раз. По контрол-Д выйдите из программы - посмотрите содержимое того файла.
2). То же самое, но в процессе ввода, запустите второй терминал, и подглядывайте в содержимое того файла... удивитесь, но скорее всего оно и там будет появляться после нажатия вам энтера построчно...
3). Запуститесь с перенаправлением и ввода и вывода -
и увидете как она скопирует ваш ранее введенный файл во второй...
Вопрос: если вы захотите ввести 10 мегабайт текста, чтобы их программа потом "скопировала" - они где должны находиться между тем моментом, когда вы их вводите, и тем, когда их уже "скопировали", скажем, на экран??
Обратите внимание на свой код: он работает посимвольно - т.е. каждый символ при вводе должен тут же выводиться. Когда вы не перенаправляете вывод (как в примере выше) - он выводится на ваш же терминал - вы получаете режим эхо - вводите hello, а видите на экране hheelllloo. Если выключить буферизацию терминала - вы именно это и получите. При перенаправлении вывод уходит в другой файл а не терм, и это эхо оседает там.
Ввод-вывод терма и файловый - буферизован. Для терминала - проброска буфера осуществляется по заполнении (не знаю сколько, в фаре в виндах 256 символов кажецо наблюдал) или при появляении там символа новой строки. Для файла - по заполнении. Это - установки по-умолчанию, их можно и переключать. Поэтому то, что вы ввели - оседает в буфере терминала, а при ньюлайт - отправляется программе, которая получает наконец, только в этот момент, все что вы там туктук, и _посимвольно_, но все что есть, выводит куда положено.
Программа-то у вас с нажатием "ентер" не завершилась? Можете вводить дальше? Ну так и вводите. Она будет дальше копировать.
Контрол-Д - это к Си отношения не имеет, это стандартнейшее сочетание "горячих клавиш" терминального режима в той системе, на форуме которой вы задали вопрос. Примерно такое же, как в виндоус "кнопка "Пуск"", Альт-Ф4, или контрол-S.
И обратите внимание - только после этого нажатие программа завершит выполнение и копирование прервется.
Запустите ее с перенаправлением вывода:
Код: Выделить всё
./a.out > __blablablah.txt
1). И дальше вводите что хотите, и нажимайте ентер сколько угодно раз. По контрол-Д выйдите из программы - посмотрите содержимое того файла.
2). То же самое, но в процессе ввода, запустите второй терминал, и подглядывайте в содержимое того файла... удивитесь, но скорее всего оно и там будет появляться после нажатия вам энтера построчно...
3). Запуститесь с перенаправлением и ввода и вывода -
Код: Выделить всё
./a.out < __blablablah.txt > __blablablah222.txt
и увидете как она скопирует ваш ранее введенный файл во второй...
Вопрос: если вы захотите ввести 10 мегабайт текста, чтобы их программа потом "скопировала" - они где должны находиться между тем моментом, когда вы их вводите, и тем, когда их уже "скопировали", скажем, на экран??
Обратите внимание на свой код: он работает посимвольно - т.е. каждый символ при вводе должен тут же выводиться. Когда вы не перенаправляете вывод (как в примере выше) - он выводится на ваш же терминал - вы получаете режим эхо - вводите hello, а видите на экране hheelllloo. Если выключить буферизацию терминала - вы именно это и получите. При перенаправлении вывод уходит в другой файл а не терм, и это эхо оседает там.
Ввод-вывод терма и файловый - буферизован. Для терминала - проброска буфера осуществляется по заполнении (не знаю сколько, в фаре в виндах 256 символов кажецо наблюдал) или при появляении там символа новой строки. Для файла - по заполнении. Это - установки по-умолчанию, их можно и переключать. Поэтому то, что вы ввели - оседает в буфере терминала, а при ньюлайт - отправляется программе, которая получает наконец, только в этот момент, все что вы там туктук, и _посимвольно_, но все что есть, выводит куда положено.
Программа-то у вас с нажатием "ентер" не завершилась? Можете вводить дальше? Ну так и вводите. Она будет дальше копировать.
Контрол-Д - это к Си отношения не имеет, это стандартнейшее сочетание "горячих клавиш" терминального режима в той системе, на форуме которой вы задали вопрос. Примерно такое же, как в виндоус "кнопка "Пуск"", Альт-Ф4, или контрол-S.
И обратите внимание - только после этого нажатие программа завершит выполнение и копирование прервется.
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Второй шаг в программировании на С
Всем спасибо. Буду разбираться. Просьба тему пока не закрывать- вдруг ещё что напишу. Раз мы уж тут все с вами познакомились, вопрос: Брайан Оверленд, "С++ без страха", (Москва, издательство "Триумф", 2005)- подойдёт таккая книга для подспорья в изучении, что ли?
И в благодарность за то, что вы со мной здесь все возились, прелюбопытнейшая, на мой взгляд, хохма про язык C и про UNIX! (см. там сообщение №3)
http://forum.vstre4a.info/topic1786329.html
И в благодарность за то, что вы со мной здесь все возились, прелюбопытнейшая, на мой взгляд, хохма про язык C и про UNIX! (см. там сообщение №3)
http://forum.vstre4a.info/topic1786329.html
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 482
- Статус: Линуксоид-Самовар :)
- ОС: Mandriva Power Pack 2008.0 LCE
Re: Второй шаг в программировании на С
Для начинающих самое то... что доктор прописал: без излишней информации, язык изучается шаг за шагом, поблочно...
Только написана под вынь, ну думаю, для изучения основ языка это не важно в какой системе вы будете работать, тем более синтаксис там описан общефункциональный, а примеры будут компилироваться и в Linux. Удачи.
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Второй шаг в программировании на С
Разобрался с вышеизложенным, так другой вопрос возник.
Cмотрите. По условию если вводимый символ есть "ctrl+d", программа должна прекратить работу. На деле же получается так: жму, допустим abc "ctrl+d". abc копируется (по причине? "ctrl+d" включает в себя команду считать? ), получаю такую строку: abcabc (первое abc я ввёл, второе машина считала и вывела). А программа работу не закончила, хоть и было введено "ctrl+d". Можно продолжать дальше вводить символы и они будут считываться и выводиться. Почему?
Cмотрите. По условию если вводимый символ есть "ctrl+d", программа должна прекратить работу. На деле же получается так: жму, допустим abc "ctrl+d". abc копируется (по причине? "ctrl+d" включает в себя команду считать? ), получаю такую строку: abcabc (первое abc я ввёл, второе машина считала и вывела). А программа работу не закончила, хоть и было введено "ctrl+d". Можно продолжать дальше вводить символы и они будут считываться и выводиться. Почему?
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 229
- ОС: Debian
Re: Второй шаг в программировании на С
http://www.intuit.ru/department/se/pposix/9/
EOF
При каноническом режиме ввода при получении этого символа все буферизованные байты передаются процессу, а сам символ EOF отбрасывается. Таким образом, если буферизованных байт нет, т. е. EOF встретился в начале строки, в процесс будет передано нуль байт, что и является стандартным обозначением конца файла.
А ведь когда-то не боялись мы программы любой,
И с одним лишь debug'ом выходили на бой,
И искусно написанный вирус встречали как брата
И с одним лишь debug'ом выходили на бой,
И искусно написанный вирус встречали как брата
-
- Сообщения: 436
- Статус: Интересующийся новичок
- ОС: Debian GNU/Linux 4 & 5
Re: Второй шаг в программировании на С
По условию если вводимый символ есть "ctrl+d", программа должна прекратить работу.
Это неверное условие, выкиньте его. Терминал направляет программе сигнал прерывания по "ctrl+c". Если программа не переопределяет обработчик сигнала, то вызывется штатный, который сразу завершает ее работу.
По контрол-Д условно говоря в поток ввода помещается ЕОФ. Т.е. когда программа в считывании данных доходит до него, у нее "ввод заканчивается". Многие программы (tr, sed, grep, cat,head, etc.) при этом завершают работу - путем штатного выхода по условию.
Debian GNU/Linux 4 -- AMD Athlon64 3000+ / Asus 7600GS -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
Debian GNU/Linux 5 -- Dell (Vostro) 500 (Celeron M560 / iGM965) -- Gnome
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Второй шаг в программировании на С
То есть я так понял, что когда программа считает все символы и дойдёт до EOF, она этот символ не считывает, а просто ждёт дальнейших команд. А если это так, тогда условие
Код: Выделить всё
(c!= EOF)
выполняется всегда, ведь EOF никогда не будет считана, а значит, значение EOF не будет присвоено переменной с. А это, в свою очередь, значит, что из программы можно выйти только ctrl+c. Этот выход мыслится мне как аварийный. Вот тебе и программа...
Можно выйти, набрав abc<ctrl+d><ctrl+d>, (abc просто как пример набора символов). Тогда ещё непонятнее. Получается, после первого ввода <ctrl+d>, <ctrl+d> не считалось, а удалилось. Но второе <ctrl+d> считалось (по причине?) и программа нормально завершила работу. Почему же первое <ctrl+d> не считывается, а второе считывается? А вот, напомню, текст программы.
Код: Выделить всё
#include <stdio.h>
main () {
int c;
c= getchar();
while (c!= EOF) {
putchar (с);
c= getchar ();
}
}
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Второй шаг в программировании на С
Это условие не я придумал, а оно прописано в K&R.
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Второй шаг в программировании на С
А не так ли обстоят дела, что когда второе
это значило только то, что
Так? Всё равно непонятно. Как в этом случае из цикла-то программа выходит? Неравенство-то всё равно выполняется!
это значило только то, что
Так? Всё равно непонятно. Как в этом случае из цикла-то программа выходит? Неравенство-то всё равно выполняется!
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Второй шаг в программировании на С
Да всё не так! getchar() возвращает символ из потока, и EOF в случае ошибки, информация о том, какая именно ошибка записано в extern int errno; В данном случае ошибка заключается в том, что читать больше нечего, а мы пытаемся.
И нет никакого символа EOF и ctrl+c!!!
getchar() именно потому возвращает int а не char, что ей надо вывести символ, или несимвол в случае ошибки. getchar() вернёт EOF и в том случае, когда есть что читать, но злой root запретил доступ к этому файлу. В этом случае в errno запишется EACCES, что значит: доступ закрыт.
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Второй шаг в программировании на С
По запуску программы набираем abc<ctrl+ d>. ПОсле этого имеем в буфере
01100001 01100010 01100011 минусодин
После этого программа начинает выполняться. По напечатании abc... Дальше вообще ничего не понять: минус один должен присвоиться переменной с, потом должна осущестьвиться проверка: не равно ли с минус один. Ага, равно. Значит, выходим из цикла. Что не так? На деле выход из цикла происходит после двойного <ctrl+ d>, а после одинарного не происходит.
01100001 01100010 01100011 минусодин
После этого программа начинает выполняться. По напечатании abc... Дальше вообще ничего не понять: минус один должен присвоиться переменной с, потом должна осущестьвиться проверка: не равно ли с минус один. Ага, равно. Значит, выходим из цикла. Что не так? На деле выход из цикла происходит после двойного <ctrl+ d>, а после одинарного не происходит.
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Второй шаг в программировании на С
Да какой минусодин??? нет там минусодин, и EOF нет. И кто вам сказал, что EOF это минус один!?
Происходит следующее:
1)Вы запускаете программу и она начинает работать до входа в функцию getchar().
2)внутри этой функции происходит чтение символа из потока stdin
3)если поток привязан к терминалу(а это не всегда так) мы ждём когда произойдёт одно из трёх событий:
а)появится символ (всё равно какой), getchar() его возвращает и программа продолжается.
б)символы кончились(мы нажали на ctrl+d), возвращаем EOF, программа продолжается.
То что в вашей консоле ввод буферезирован ничего не значит. Для getchar() это не клавиатура, это поток.
в)прерывание(например нажали ctrl+c) программа прерывается.
А в буфере будет 'a','b','c', если вам это интересно, о том, что после 'c' ничего нет, getchar() узнает так-же, как о том, что в файле нулевой длинны(например /dev/null) нет ни одного символа.
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Второй шаг в программировании на С
Что за шутки?
Код: Выделить всё
#include <stdio.h>
int main () {
printf ("%d\n", EOF);
return 0;
}
В конце концов http://ru.wikipedia.org/wiki/EOF
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Второй шаг в программировании на С
Реальное значение EOF является отрицательным числом, зависящим от системы (в основном −1), что гарантирует несовпадение с кодом символа.
Простите, вы читать умеете? Где тут написано, что EOF всегда и везде -1. По русски же написано: в основном.
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Второй шаг в программировании на С
У меня код (см. выше) выдаёт минус один. Это и есть значение EOF. А потом: мы же данные-то куда вводим, если не в буфер? Интересно получается: a, b, c мы забили в буфер, а EOF в другое место, что ли? Тогда скажите, как оно называется. Да в конце концов у меня всё туда забивалось, все нечитаемые символы. Я на основании чего должен предполагать, что именно EOF куда-то в другое место забилось?
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Второй шаг в программировании на С
Я не знаю, привязан у меня поток к терминалу или нет. Честно говоря, что такое "привязан к терминалу", я тоже не знаю. В моих книгах про это ничего не написано.
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 8735
- Статус: GPG ID: 4DFBD1D6 дом горит, козёл не видит...
- ОС: Slackware-current
Re: Второй шаг в программировании на С
Это у вас. А почему вы думаете, что все компьютеры поддерживают отрицательные числа? А почему не -2?
Ну вводим, ну в буфер, ну данные. Но EOF это не данные, мы его никуда не вводим, и в буфер он не влезет. Потому что EOF это не символ.
Никак не называется. Ну пускай будет /dev/null Это хранилище EOF'ов специально для вас. Все EOF'ы туда направляются, и вы сможете в любое время считать оттуда необходимое их количество.

-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Второй шаг в программировании на С
Эту программу не я придумал, она взята мной из K&R. И там чёрным по белому написано, что функция getchar () возвращает символ за символом. И возвращаемые ей символы находятся в буфере. Так? А теперь: как может эта функция возвратить значение чего-либо, если это что-либо (в данном случае символическая константа EOF) не в буфере, а в другом месте? getchar () ведь считывает данные из буфера только, так ведь?
...Да в конце концов, если EOF- суть конец файла (смею думать), а в данном случае обозначает конец входного потока, где же ей находиться, если не в конце этого потока? А сам поток в буфере.
...Да в конце концов, если EOF- суть конец файла (смею думать), а в данном случае обозначает конец входного потока, где же ей находиться, если не в конце этого потока? А сам поток в буфере.
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?
-
- Сообщения: 482
- Статус: Линуксоид-Самовар :)
- ОС: Mandriva Power Pack 2008.0 LCE
Re: Второй шаг в программировании на С
promov писал(а): ↑30.12.2007 17:29Эту программу не я придумал, она взята мной из K&R. И там чёрным по белому написано, что функция getchar () возвращает символ за символом. И возвращаемые ей символы находятся в буфере. Так? А теперь: как может эта функция возвратить значение чего-либо, если это что-либо (в данном случае символическая константа EOF) не в буфере, а в другом месте? getchar () ведь считывает данные из буфера только, так ведь?
А Вы разорбрались, что такое буфер? Нужно с этого начинать, Смею Вас заверить, как только в этом разберетесь, так сразу все Ваши вопросы сами собой исчерпаются...
-
- Сообщения: 282
- ОС: Debian GNU/Linux Lenny
Re: Второй шаг в программировании на С
скомпилил в msvs вот что получил:
получается getchar() возвращает Ctrl+D как обычный сканкод, собственно поэтому оно и возвращает инт - в старшем байте клавиша модификатор, в младшем буква.
Код: Выделить всё
D:\Games\Musor\Project\!MS VS Projects\void\debug>void.exe
sdfsdfds
sdfsdfds
sdfsd^D
sdfsd♦
gkljhfkkl^D
gkljhfkkl♦
^C
D:\Games\Musor\Project\!MS VS Projects\void\debug>
получается getchar() возвращает Ctrl+D как обычный сканкод, собственно поэтому оно и возвращает инт - в старшем байте клавиша модификатор, в младшем буква.
-
- Сообщения: 384
- Статус: Участник
- ОС: Debian GNU/Linux
Re: Второй шаг в программировании на С
Да, разобрался. Вот в этой теме.
Моя концепция буферизации
читать только первый пост. К нему одна небольшая поправка: буфер заполняется с крайнего левого элемента (если схематично). Если что-то поправите, буду очень благодарен!
Зачем хорёк пошел в ларёк, зачем барсук полез на сук...
Мораль легко уразуметь: зачем на бал пришёл медведь?
Мораль легко уразуметь: зачем на бал пришёл медведь?