# include <conio.h>
#include <string.h>
void main()
{
char c; int i; long 1; float f; double d; long double 1d;
unsigned int ui;
int Age; char str[10]; char*pc;
clrscr();
рrintf("\nВведите символ с=");
fflush(stdin); scanf("%c", &c);
printf("Введено с - %c", c);
printf("\nВведите через пробел целое и длинное целое"); fflush(stdin); int j=scanf("%d %ld", &i, &1);
printf("Введено %d аргументов:i = %i, 1 = %ld", j, i, 1 ) ;
printf("\nВведите беззнаковое целое");
fflush(stdin); scanf("%u", &ui);
printf("Введено ui = %u", ui);
printf("\nВведите через запятую вещ.числа float, double и\
long double\n");
fflush(stdin); scanf("%f,%lf,%Lf", & f, &d, &ld); //фиксир.\
//или плав. точка
printf("\Введено float = %g, double = %g, long double =\
%Lg",f,d,ld);
printf("\nВведите строку\n");
fflush(stdin); scanf("%10s", str); //фиксир. или плав. точка
printf("Введена строка %s", str);
printf("\nВведите адрес ячейки\n" );
fflush(stdin); scanf("%Fp", &pc); //фиксир. или плав. точка
printf("Введен адрес %Fp, содержимое ячейки по этому\
адресу %с", рс, *рс );
do
{
fflush(stdin);
printf("\nВведите возраст:");
}
while( scanf("%d", &Age) != 1 || 0 > Age || Age > 100);
fflush(stdin);
printf("\nВозраст = %d", Age);
if(!getch())getch();
}
Пример 4.
Найти первое целое число в текстовом файле.
#include <stdio.h>
void main()
{
char str[1000];
int i;
FILE *fp = fopen("ex.txt", "w+"); // Проверка опущена!
fputs("Год 1997 - число простое", fp);
rewind(fp);
fscanf(fp, "%[^0-9]%i", str, &i);
printf("\nПредыдущие символы :%s\nпeрвoe число = %i",
str, i);
}
Вопрос. Как правильно "заморозить" экран?
Ответ. Некорректно использовать для этой цели вызов функции ввода символа с клавиатуры
getch();
Он нормально сработает, если "разморозить" экран нажатием клавиши, имеющей однобайтовый ascii-код. Это -такие клавиши, как Esc, Enter, Tab, буквы, цифры основной клавиатуры, и т.д.. Функция getch() считывает этот код, и программа продолжается. Но при нажатии некоторых других клавиш в буфер ввода-вывода с клавиатуры записываются два числа: 0 и расширенный код, совпадающий, как правило, со scan-кодом клавиши. Функция getch() считает 0, программа продолжится, а при последующем вызове getch() будет считан оставшийся, ненужный scan-код. Даже если getch() стоял в конце программы, то при повторном запуске программы буфер ввода-вывода с клавиатуры не будет очищен, getch() считает scan-код и программа не "заморозится". Таким образом, программа будет приостанавливаться через раз ! Правильнее будет вставить строку
if( !getch()) getch();
Другой вариант - ожидание в бесконечном цикле нажатия клавиши
while( !kbhit());
Он подходит только в конце программы, т.к. дальнейший вызов getch() считает случайно нажатую клавишу.
Вопрос. Как правильно использовать scanf при вводе?
Ответ. Допустим нужно ввести с клавиатуры возраст человека в переменную Age типа int.
do
{
fflush(stdin);
printf("\nВведите возраст:");
}
while(scanf("%d", &Age) != 1);
fflush(stdin);
printf("\nВозраст = %d", Age); //Отладочная проверка
В реальной программе желательно произвести проверку на осмысленность введенного значения. В данном случае, вероятно, 0 <= Age <= 100. Тогда условие в цикле while может принять вид
while( scanf("%d", & Age) != 1|| 0 > Age || Age > 100);
Получается довольно сложный код, но информация вводится в программу нечасто, а обрабатывается достаточно долго, поэтому стоит потратить усилия на обеспечение корректного ввода.
Таблица 7
Назначение | Имя функции | С каким работает потоком | Особенности | ||
Файл | stdin/ stdout | Консоль | |||
1.Ввод символа | getc, fgets | X X | - - | - - | макро, эхо функция, эхо |
getchar, fgetchar | - - | X X | - - | макро, Enter функция, Enter | |
getch getche | - - | - - | X X | без эха, без Enter эхо, без Enter | |
kbhit ungetc ungetch | - X - | - - - | X - X | ||
2.Вывод символа | putc putchar putch | X - - | - X - | - - X | |
З.Ввод строки | fgets gets cgets | X - - | - X - | - - X | с проверкой без проверки с проверкой |
4. Вывод строки | fputs puts cputs | X - - | - X - | - - X | без CR/LF cCR/LF без CR/LF |
5.Форматный ввод | fscanf scanf cscanf sscanf | X - - - | - X - - | - - X - | ввод из строки |
6.Форматный вывод | fprintf printf cprintf sprintf | X - - - | - X - - | - - X - | Вывод в строку |
Замечания:
1. Под консолью понимается клавиатура при вводе и дисплей (или монитор) при выводе информации.
2. По умолчанию под стандартным вводом stdin понимается ввод с клавиатуры, под стандартным выводом stdout понимаетсявывод на монитор. Кроме них, существуют другие стандартные потоки:
- stderr - устройство стандартного вывода ошибок (монитор),
- stdaux - вспомогательное устройство (последовательный
com-порт)
- stdprn - принтер (параллельный 1tp-порт) Потоки stdin/stdout нельзя легально перенаправить программным способом в файл, т. к. они являются макроопределениями. Но перенаправление можно осу ществить с помощью команды DOS >. Например,
hello.exe > ex.txt
В этом случае все, что шло в поток stdout, пойдет в файл ex.txt.
Например,
#include <stdio.h>
#include <conio.h>
#include <mem.h>
void main()
{
clrscr();
FILE *fp = fopen("exl.txt", "w+");
if(fp = NULL)
{
рerrоr("Ошибка при открытии файла"); // вывод в stderr return;
};
FILE *pbuf=stdin; int с = getc(stdin);
fclose(fp);
}
Прототипы:
int fgetc(FILE *stream);
int getc(FILE *stream);
Возвращает: символ, расширенный до int без продолжения знака. В случае ошибки или конца файла возвращает EOF ( = -1 = 0xFFFF).
Описание. Считывает очередной символ из входного потока и увеличивает указатель текущего положения (СР - current position) на 1. При вводе с клавиатуры (stream=stdin) выполняется после нажатия клавиши Enter. Макрокоманда getc полностью аналогична функции fgetc. В файле stdio.h определена, как
#define getc(f) ((--((f)->level) >= 0) ? (unsigned char)(*(f)-->curp++) \ :_fgetc (f))
Разберите синтаксис этого макроса !
Хотя getc и fgetc аналогичны, но лучше пользоваться макросом по следующей причине. Чтение из файла происходит блоками по 256b, 512b и т.д. После обработки одного блока в ОЗУ с диска считывается следующий блок. Макрос работает с текущим блоком напрямую, как видно из определения, и обращается к функции fgetc только после обработки этого блока. Функция fgetc также работает с блоком в ОЗУ, но каждое обращение к нему реализуется через вызов функции. Таким образом, использование getc увеличивает скорость за счет увеличения кода. Использование fgetc уменьшает код ценой уменьшения скорости.
Прототипы: int fgetchar(void);
int getchar(void);
Возвращает : символ, расширенный до int без продолжения знака. В случае ошибки или конца файла возвращает EOF. Описание. Считывает очередной символ из стандартного входного потока и увеличивает СР на 1. Поток stdin, как и любой открытый файл, имеет буфер с размером по умолчанию 512b. Функция выполняется после нажатия клавиши Enter, после чего вводит 1 символ. Остальные введенные символы остаются в буфере, ожидая своей участи. Макрос getchar аналогичен функции fgetchar.
Прототипы: int getch(void);
int getche(void);
Возвращают: символ, расширенный до int без продолжения знака.
Описание. Функция getch выводит символ на монитор, getche - не выводит. Функции имеют буфер на два символа: в случае нажатия
клавиши с расширенным кодом туда записывается 0 и scan-код нажатой клавиши. Не ожидают нажатия Enter. Буфер не очищается даже при повторном запуске программы.
Прототип: int kbhit(void);
Возвращает : 1, если к моменту вызова функции была нажата, но не обработана какая-нибудь клавиша; 0-в противном случае.
Описание. Функция оставляет коды нажатой клавиши в буфере ввода-вывода с клавиатуры, так что их можно прочитать, например, с помощью getch.
Прототип: int ungetc(int d,FILE*stream);
Возвращает: символ d, посланный обратно во входной поток stream, и EOF в случае ошибки.
Описание. Выталкивает символ d обратно во входной поток stream. Вернуть можно только один символ. Следующее чтение из потока вернет символ d. Символ с расширенным кодом вернуть не удастся.
Функция ungetch
Прототип: int ungetch(int d);
Описание. Аналогична ungetc, но выталкивает символ d обратно в буфер клавиатуры.
Прототип: char *fgets(char *target, int n, FILE * stream); Описание. Вводит из stream не более n символов в строку по адресу target. Ввод заканчивается при встрече символа \n. Возвращает target при успешном вводе и NULL при встрече конца файла или в случае ошибки.
Прототип: char *gets(char *target);
Описание. Вводит из stdin строку по адресу target. Число вводимых символов не ограничено. В остальном похожа на fgets.
Прототип: char *cgets(char *target);
Описание. Читает строку из консоли. str[0] должно содержать максимальную длину вводимой строки. По окончании str[l] содержит число реально введенных символов. Введенная строка начинается с элемента str[2]. Для перехода на новую строку в формат нужно вставить два символа: \n\r. Возвращает начало введенной строки str[2].
Прототип : int fputs(const char *s, FILE *stream);
Описание. Записывает строку в поток. Возвращает последний записанный символ.
Функция puts
Прототип: int puts(const char *s);
Описание. Записывает строку в поток stdout. Возвращает последний записанный символ.