Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / C++ Новый топик    Ответить
 как все же работает getchar  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
Добрый день.

Кто мне объяснит как работает функция getchar()
на примере вот такого кода из книги Кернигана:
#include <stdio.h>
int main() {
    int c;
    c = getchar();
    while (c != EOF)
    {
        putchar(c);
        c = getchar();
    }
}


Я тут не понимаю "кто" (каким образом) считывает как бы строку с клавиатуры. Предполагаю, что возможно(может и неверно), что вот эта строка в цикле c = getchar(); она как бы двигает маркер в потоке символов и выдаёт по одному символу в переменную c. но когда поток пуст функция работает как что-то вроде считывания строки с клавиатуры до того как кто-то не нажал Ctrl+z. Как только нажали эту комбинацию строка помечается символом EOF и поток считается законченным.
Если моё предположение верно, то тогда всё ясно.
29 фев 20, 22:52    [22089886]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 49957

В зависимости от системы (и прочих опций stdin) ввод с клавиатуры может буферизироваться
до нажатия клавиши "Enter" и в программу попадать только после этого. Так удобнее: можно
отредактировать опечатки.

Posted via ActualForum NNTP Server 1.5

29 фев 20, 23:09    [22089889]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
Dimitry Sibiryakov

В зависимости от системы (и прочих опций stdin) ввод с клавиатуры может буферизироваться
до нажатия клавиши "Enter" и в программу попадать только после этого. Так удобнее: можно
отредактировать опечатки.


это даже не самое главное тут . мне непонятно кто читает с клавы символы . всё указывает на то, что это делает c=getchar() в случае если буфер пуст, а если не пуст, то двигает маркер и выдаёт символ, вычищая его из буфера до тех пор пока не вычистит весь буфер , а потом опять считывает с клавы и т.д. по циклу. но пока это только мои фантазии. так как я нигде ответа на мой вопрос не нашёл. ни в книге, ни в гуглях.

Сообщение было отредактировано: 29 фев 20, 23:19
29 фев 20, 23:15    [22089892]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 49957

andron81
мне непонятно кто читает с клавы символы

Контроллер клавиатуры. Он отправляет их в системный блок. Там они попадают в драйвер
клавиатуры. Оттуда - в буфер операционной системы. Потом в буфер stdin. и вот оттуда уже
их вычитывает getchar(). А если в stdin пусто, он ждёт пока операционка чего-нибудь туда
не покладёт.

Posted via ActualForum NNTP Server 1.5

29 фев 20, 23:33    [22089897]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
Dimitry Sibiryakov

andron81
мне непонятно кто читает с клавы символы

Контроллер клавиатуры. Он отправляет их в системный блок. Там они попадают в драйвер
клавиатуры. Оттуда - в буфер операционной системы. Потом в буфер stdin. и вот оттуда уже
их вычитывает getchar(). А если в stdin пусто, он ждёт пока операционка чего-нибудь туда
не покладёт.


вы написали на низком уровне. а на уровне Cи кто это делает ?
хорошо давайте упростим . давайте по тупому ))) перепишем так :

int main() {
int c;
    }

программа запустилась и не дала мне ввести никакую строку.

то ли дело если я напишу вот так :
int main() {
    int c;
   c = getchar()
    }


а тут уже даст ввести какую-то строку. а почему ???
29 фев 20, 23:45    [22089899]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
Алексей Роза
Member

Откуда: РФ
Сообщений: 144
потому что ф-я getchar() запускает ожидание события (нажатия на кнопку)
а потом обрабатывает его

Сообщение было отредактировано: 1 мар 20, 01:26
1 мар 20, 01:25    [22089914]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 49957

andron81
а на уровне Cи кто это делает ?

Какую букву из "stdin" ты не заметил в описании сабжа?

Posted via ActualForum NNTP Server 1.5

1 мар 20, 01:32    [22089918]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6491
andron81
вы написали на низком уровне. а на уровне Cи кто это делает ?

На уровне С под капотом происходит следующее.
Каждая программа запускается сразу с 3-мя уже открытыми файлами под дескрипторами 0, 1, 2.
Файл 0 отвечает за ввод из терминала (хотя при необходимости командная оболочка может перенаправить туда любой файл или вывод другой программы).
Рантайм С берет дескриптор 0 и подкючает его к глобальному объекту stdin, который представляет собой буферизированный файловый поток (стандартный тип в С: FILE). Остальные тоже подключаются в свои потоки.
При чтении из stdin происходит чтение из дескриптора 0, которое в свою очередь приводит к чтению вводимых в терминале символов (перенаправление не рассматриваем). Если ввода еще не было, то операция чтения блокирует вызывающй код пока либо что-то не введут, либо не будет достигнут "конец файла" (обычно при перенаправлении файлов, хотя и в терминале тоже можно ввести конец файла.).
Фунция getchar просто читает один символ из stdin.
Если никакого чтения не делать то программа просто завершается, без ожидания, потому что ожидание происходит именно во время операции чтения.
1 мар 20, 01:58    [22089921]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
[quot Anatoly Moskovsky#22089921]
andron81

Фунция getchar просто читает один символ из stdin.
Если никакого чтения не делать то программа просто завершается, без ожидания, потому что ожидание происходит именно во время операции чтения.

тогда непонятно вот тут если пройтись отладчиком первая строчка c = getchar(); отрабатывает ввод с клавиатуры . затем после нажатия "Enter" мы начинаем хождение по циклу. доходим до первой строки c = getchar(); происходит операция чтения , но ожидания ввода почему не происходит (или происходит, но я его не вижу :) )?
#include <stdio.h>
int main() {
    int c;
    c = getchar();
    while (c != EOF)
    {
        putchar(c);
        c = getchar();
    }
}
1 мар 20, 10:11    [22089956]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
Basil A. Sidorov
Member

Откуда:
Сообщений: 10141
Символьный ввод-вывод (типично) построчный и буферизированный.
Если буфера и строки нет в вашей программе, это ещё не значит, что их нет вообще нигде.
1 мар 20, 12:04    [22089982]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
Basil A. Sidorov
Символьный ввод-вывод (типично) построчный и буферизированный.
Если буфера и строки нет в вашей программе, это ещё не значит, что их нет вообще нигде.


да кто ж против то.

символы кто считывает ? словно readln в паскале
я полагаю, что getchar и считывает, если буфер пуст, а если не пуст , то не считывает , а выдаёт символ за символом из буфера.
1 мар 20, 14:03    [22090042]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 49957

andron81
символы кто считывает ?

stdin.

Posted via ActualForum NNTP Server 1.5

1 мар 20, 14:15    [22090053]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
mayton
Member

Откуда: loopback
Сообщений: 46322
По сути в статической инициализации main процесса работает нечто вроде

FILE *STDIN = fopen(STDIN_FILENO); // Открыть файл стандартного ввода с клавиуатуры
FILE *STDOUT = fopen(STDOUT_FILENO); // Открыть файл стандартного вывода на экран.
FILE *STDERR = fopen(STDERR_FILENO); // Открыть файл стандартного ввода на экран для ошибок


И

c = getchar();


эквивалентен

c = fgetchar(STDIN);


Если в консоли жоглировать птичками "<" ">" то можно переподключать эти потоки на файлы.

Например

$ ./andron.exe < keboard_stream.txt 2>&1 > log-output-and-errors.log


Здесь также поток ошибок STDERR перенаправляется в STOUT через 2>&1

Или есть более подробный синтаксис когда указываются явно дескрипторы 0,1,2 рядом с птичками
но этим обычно никто не пользуется и все пишут кратко.

Или с помощью операции pipe "|" делать конвейеры обработки когда выхлоп одной утилиты является входом другой.
1 мар 20, 14:34    [22090058]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
Anatoly Moskovsky
Member

Откуда: Odessa
Сообщений: 6491
andron81
первая строчка c = getchar(); отрабатывает ввод с клавиатуры . затем после нажатия "Enter"

Тут у вас ошибка.
Первый getchar возвращает значение только после нажатия Enter (т.к. обычно ввод с терминала буферизируется построчно). При этом возвращаемое значение - это первый введенный символ.
Остальные введенные символы включая Enter тоже читаются на этом этапе (все сразу) и складываются в буфер stdin. Последующие вызовы getchar читают прямо из буфера (как из массива) пока там что-то есть. После исчерпания буфера следующий getchar будет ждать ввода снова, и загрузит очередную порцию символов в буфер и вернет первый из них.

Сообщение было отредактировано: 1 мар 20, 21:24
1 мар 20, 21:23    [22090222]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
Anatoly Moskovsky
andron81
первая строчка c = getchar(); отрабатывает ввод с клавиатуры . затем после нажатия "Enter"

Тут у вас ошибка.
Первый getchar возвращает значение только после нажатия Enter (т.к. обычно ввод с терминала буферизируется построчно). При этом возвращаемое значение - это первый введенный символ.
Остальные введенные символы включая Enter тоже читаются на этом этапе (все сразу) и складываются в буфер stdin. Последующие вызовы getchar читают прямо из буфера (как из массива) пока там что-то есть. После исчерпания буфера следующий getchar будет ждать ввода снова, и загрузит очередную порцию символов в буфер и вернет первый из них.


ну вот это я и хотел услышать. а то все в научность ударяются.
спасибо большое

Сообщение было отредактировано: 2 мар 20, 07:53
2 мар 20, 07:53    [22090354]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
Basil A. Sidorov
Member

Откуда:
Сообщений: 10141
Сложно объяснять элементарные вещи.
От "научности" это не зависит - лично мне всегда(?) было очевидно, что система сначала читает в собственный строчный буфер и уже потом отдаёт строку (символы) приложению.

Сообщение было отредактировано: 2 мар 20, 10:58
2 мар 20, 10:56    [22090445]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 49957

andron81
ну вот это я и хотел услышать.

А ничего, что это уже было сказано в первом же ответе?..

Posted via ActualForum NNTP Server 1.5

2 мар 20, 13:30    [22090605]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
Dimitry Sibiryakov

andron81
ну вот это я и хотел услышать.

А ничего, что это уже было сказано в первом же ответе?..


ничего... так как вот этой фразы я от вас не услышал:

"После исчерпания буфера следующий getchar будет ждать ввода снова"

я собственно так и предполагал(описав в самом первом сообщении), но никто мне так и не опроверг и не подвердил кроме Московского.

Сообщение было отредактировано: 2 мар 20, 14:59
2 мар 20, 14:59    [22090701]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 49957

andron81
я собственно так и предполагал(описав в самом первом сообщении), но никто мне так и не
опроверг и не подвердил кроме Московского.

Так, может, стоит начать-таки читать ответы? Например, второй в теме:
я
А если в stdin пусто, он ждёт пока операционка чего-нибудь туда
не покладёт.

Posted via ActualForum NNTP Server 1.5

2 мар 20, 15:38    [22090744]     Ответить | Цитировать Сообщить модератору
 Re: как все же работает getchar  [new]
andron81
Member

Откуда: Смоленск
Сообщений: 834
Dimitry Sibiryakov

andron81
я собственно так и предполагал(описав в самом первом сообщении), но никто мне так и не
опроверг и не подвердил кроме Московского.

Так, может, стоит начать-таки читать ответы? Например, второй в теме:
я
А если в stdin пусто, он ждёт пока операционка чего-нибудь туда
не покладёт.



ну это уже ваше сообщение №2 . вы же говорили о первом. да и изложено в этом №2 языком который мне пока не по зубам .
3 мар 20, 08:51    [22091233]     Ответить | Цитировать Сообщить модератору
Все форумы / C++ Ответить