Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Как симитировать конец потока символов (EOF)
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Motion
Код подсчитывает количество введённых символов.
Код
#include <stdio.h>

int main(void)

{

    long nc;
    int c;
    nc=0;
    while((c=getchar())!=EOF)
        ++nc;

    printf("%ld/n", nc);

return 0;
    }


После компиляции запускается окно (console application). Начинаю вводить разные символы, нажимаю Enter, пробелы и т.д. А как симитировать EOF чтобы программа наконец вышла из цикла while() и вывела результат?
тау
в стародавние времена ДОСа вроде бы спасала комбинация клавишей CTRL+Я
если склероз не попутал
Hellper
не... поспешил
rezident
Удерживая ALT, на доп. цифровой клаве набрать 255.
SysRq
ctrl-c, или ввод из файла сделать, направив содержимое файла в stdin программы ("программа.exe <файл_с_текстом.txt")
ReAl
Цитата(Владимир_КПИ @ Oct 11 2009, 21:26) *
Код
    printf("%ld/n", nc);
"%ld\n"

Цитата(Владимир_КПИ @ Oct 11 2009, 21:26) *
А как симитировать EOF чтобы программа наконец вышла из цикла while() и вывела результат?

В DOS и Win* консоли - Ctrl-Z или, что то же самое, Alt-26 в начале строки (после чего всё равно надо ENTER, так как ввод построчно-буферизованный).
В Linux - Ctrl-D (ASCII EOT aka КП - "КонецПередачи")


Цитата(SysRq @ Oct 11 2009, 22:34) *
ctrl-c
и программа вывалится на getchar-е не дойдя до printf
SysRq
Цитата(ReAl @ Oct 11 2009, 23:44) *
и программа вывалится на getchar-е не дойдя до printf
Да, вы правы! У меня срабатывает, но это частный случай.
Motion
Цитата
"%ld\n"

Да, верно. При компиляции заметил.

Цитата
В DOS и Win* консоли - Ctrl-Z или, что то же самое, Alt-26 в начале строки (после чего всё равно надо ENTER, так как ввод построчно-буферизованный).
В Linux - Ctrl-D (ASCII EOT aka КП - "КонецПередачи")

Исчерпывающий ответ. Спасибо.
ReAl
Цитата(Владимир_КПИ @ Oct 12 2009, 21:28) *
Исчерпывающий ответ. Спасибо.
Вдогонку - это не "в С", это "в ОС".
Т.е. в dos/win
Motion
Цитата
после чего всё равно надо ENTER, так как ввод построчно-буферизованный


А вот тут возникли дополнительные вопросы.

Например здесь:
Код
#include <stdio.h>

int main(void)

{
int ch;

while ((ch=getchar())!=EOF)
{
putchar(ch);
}

return 0;
    }


у меня построчно-буферизированый ввод. Нажму Enter - введённые символы передаются программе.


А вот в этой программе он не построчно-буферизированый:

CODE
#include <stdio.h>

int main(void)

{

long newline, tab, space;
int c,chars;
chars=0;
newline=0;
tab=0;
space=0;
while((c=getchar())!=EOF)
{
++chars;
if(c==10)
++newline;
if(c==9)
++tab;
if(c==32)
++space;
}
printf("%d characters\n",chars);
printf("%ld new lines\n", newline);
printf("%ld tabs\n",tab);
printf("%ld spaces\n", space);

return 0;
}


Нажму Enter - у меня происходит переход на новую строку. И лишь после имитации EOF - введённые символы передаются на обработку программе. Почему в первой программе построчно-буфферизированый ввод, а во второй - нет?
baralgin
Владимир_КПИ Во второй программе тоже буферизированный ввод. После нажатия nl выполняется тело цикла и дальше снова "висяк" на getchar. По EOF просто выводятся рузультаты.
Motion
Цитата
Во второй программе тоже буферизированный ввод. После нажатия nl выполняется тело цикла и дальше снова "висяк" на getchar. По EOF просто выводятся рузультаты.

Теперь понял. Спасибо.

Задача: напишите программу для копирования входного потока в выходной с заменой знаков табуляции на \t, символов возврата назад (Backspace) на \b, а обратных косых чёрт - на \\. Это сделает табуляции и символы возврата легко читаемыми в потоке.

А как это должно быть? Например нажимаю табуляцию и программа сразу делает подмену в реальном времени (то есть не буферизированный ввод) или я ввожу множество символов, знаков табуляции, возвратов назад, косых чёрт и только при нажатии EOF программа всё это преобразует с подменой?
baralgin
Задача не совсем ясна. Знак табуляции это и есть '\t'. И как ловить backspace при буферизированном вводе тоже не ясно... Без последнего я вижу разве что это:
Код
    int c;
    do
    {
        switch( c = fgetc(stdin) )
        {
            case '\t':
                putchar('\\'), putchar('t');
                break;
            case '\\':    
                putchar('\\'), putchar('\\');
                break;
            default:
                putchar(c);
        }
    } while ( c != EOF );


Насчёт реального времени ничего в задании не сказано, поэтому считаем что не нужно. Иначе я вижу только GetStdHandle и ReadFile, но наверное это грех в данном случае smile.gif .
Motion
А возможна работа программы в небуферизированом режиме?
SysRq
getch(), _getch()
Motion
Цитата
getch(), _getch()


Получилось, только дополнительно необходимо подключить библиотеку conio.h.
baralgin
С функциями типа _getch/e() есть небольшая загвоздка - они не работают с stdin(и с stdout похоже тоже), а читают нажатия из буффера клавиатуры. К примеру такая программа:
Код
int main()
{
    int ch;
    while ((ch=getchar())!=EOF) putchar(ch);
    return 0;
}

при вызове таким образом: progname.exe < sometext.txt
Выведеть в консоль содержимое файла sometext.txt . Но если заменить getchar на _getch то ничего выведено не будет. Собственно _getch и EOF не возвращает wink.gif .
Использовать или нет зависит от задачи.

Владимир_КПИ если вы просто изучаете язык си, то я бы посоветовал не заострять внимания на этом моменте. Для полноценного изучения достаточно освоить вывод (имхо, конечно).

PS: http://ru.wikipedia.org/wiki/Conio.h
sigmaN
а чё, просто if( сh=='\t' ) ch = '\'; а следующий ch = 't'; в зависимости от того, куда это всё складывается. Вот и будет вам замена находу.
А уже реализовать это можно по всякому..
Ну а ежели построчно буферизированный ввод, тогда после ввода перебрать поступивший массив на наличие '\t' и точно так-же произвести замену.
Удобнее всего делать это, копируя в другой массив. Будет перерасход памяти, но для начала пойдет. Да и для конца тоже smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.