p аргумент - ближній покажчик | l | d, i, o, u, x, X аргумент - long int | L | e, E, f, g, G аргумент - double (тільки для scanf) | L | e, E, f, g, G аргумент - long double |
Приклад 1. # Include <stdio.h> # Include <math.h> # Include <conio.h> # Include <string.h> void main () { clrscr (); printf ("\ nHello, World!"); printf ("\ nЗаголовкі стовпців: \ n \" Січень \ "\ t \ t \" Інші \ місяці ... \ ""); printf ("\ nОшібка! \ 007"); / / звуковий сигнал int i = 1828; printf ("\ nПолний адресу змінної i =% Fp, зсув = \ % Np ", & i, & i); printf ("\ nТолстой народився у% d році, а число е =%. 9 f ", i, М_Е); printf ("\ nМожливо помилка% s: аргументів менше, ніж \ специфікатором "); / / Різні системи числення 33 = 0x21 = 041 printf ("\ n% i =% # х =% # 0о", i, i, i); char j = 5, str [80] = ""; / / Рядок з 5 повторюваними символами - while (j -) strcat (str ,"-"); / / Memset (str, '-', 5); / / інший варіант printf ("\ n% s", str); int n = printf ("\ nДанний виклик printf вивів"); printf ("% i символів, враховуючи переклад рядка (1 символ)", n); if (! getch ()) getch (); / / затримка екрану } 3. Функція scanf Призначена для введення змінного числа аргументів зі стандартного потоку вводу stdin. Перед введенням аргументи піддаються форматування. Повертає число реально введених аргументів (не символів!). Поміщає дані, що вводяться за адресами, що містяться в аргументах, тобто аргументи передаються цієї функції за адресою. Функція припиняє свою роботу при першому невдалому введенні. Якщо не всі дані введені успішно, то необхідно очистити буфер вхідного потоку за допомогою функції fflush (stdin); В іншому випадку при наступному виклику scanf будуть вводитися не введені раніше дані. Бажано очищати буфер і перед першим викликом scanf. Синтаксис: int scanf (const char * format [, ...]); Перший і обов'язковий аргумент format представляє собою строкову константу і містить тільки специфікатора введення і їх роздільники (див. таблиці для printf). Текст використовувати не можна. Уточнення до таблиць специфікатором: Для введення в змінні типу double потрібно використовувати специфікатор% 1 f, а для введення long double -% Lf. В якості роздільників специфікатором можна використовувати пробіл або будь-який символ пунктуації. Обраний роздільник має поділяти і дані, що вводяться. В іншому випадку буде введено тільки перше дане. Функція scanf не перевіряє для рядків вихід з діапазону, тому для рядків у форматі потрібно вказувати довжину вводиться рядка. Наприклад, для рядка char str [10] специфікатор повинен мати вигляд% 10 s. В іншому випадку якщо вводиться рядок більше буфера, то буфер буде переповнений, що може викликати "добре приховану" помилку. Функція допускає можливість фільтрації інформації, що вводиться. Введення припиняється при першій зустрічі символу, відсутнього у фільтрі. Особливо ефективно при введенні даних з файлу.
Приклад 2. char str [100]; scanf ("% [A - Za - z]", str); / / введення до першого нелітерних символу scanf ("%[-+. 0-9] ", str); / / введення дійсного числа в рядок scanf ("%[^-. 0-9] ", str); / / введення будь-яких символів, поки не \ / / Зустрінеться одне з перерахованих після ^ Приклад 3. # Include <stdio.h> # Include <math.h> # 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); } 4. Питання та відповіді Питання. Як правильно "заморозити" екран? Відповідь. Некоректно використовувати для цієї мети виклик функції введення символу з клавіатури 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); Виходить досить складний код, але інформація вводиться в програму нечасто, а обробляється досить довго, тому варто витратити зусилля на забезпечення коректного введення. 5. Огляд функцій вводу-виводу Таблиця 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 - | Висновок в рядок |
Зауваження: Під консоллю розуміється клавіатура при введенні і дисплей (або монітор) при виведенні інформації. За замовчуванням під стандартним вводом 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); } Функція fgetc і макрокоманда getc Прототипи: int fgetc (FILE * stream); int getc (FILE * stream); Повертає: символ, розширений до int без продовження знака. У разі помилки або кінця файлу повертає EOF (= -1 = 0 xFFFF). Опис. Зчитує черговий символ з вхідного потоку і збільшує покажчик поточного становища (СР - current position) на 1. При введенні з клавіатури (stream = stdin) виконується після натискання клавіші Enter. Макрокоманда getc повністю аналогічна функції fgetc. У файлі stdio. H визначена, як # Define getc (f) ((--(( f) -> level)> = 0)? (Unsigned char) (* (f) -> curp + +) \: _fgetc (f)) Розберіть синтаксис цього макросу! Хоча getc і fgetc аналогічні, але краще користуватися макросом з наступних причин. Читання з файлу відбувається блоками по 256 b, 512 b і т.д. Після обробки одного блоку в ОЗУ з диска зчитується наступний блок. Макрос працює з поточним блоком напряму, як видно з визначення, і звертається до функції fgetc тільки після обробки цього блоку. Функція fgetc також працює з блоком в ОЗУ, але кожне звернення до нього реалізується через виклик функції. Таким чином, використання getc збільшує швидкість за рахунок збільшення коду. Використання fgetc зменшує код ціною зменшення швидкості. Функція fgetchar і макрокоманда getchar Прототипи: int fgetchar (void); int getchar (void); Повертає: символ, розширений до int без продовження знака. У разі помилки або кінця файлу повертає EOF. Опис. Зчитує черговий символ зі стандартного вхідного потоку і збільшує СР на 1. Потік stdin, як і будь-який відкритий файл, має буфер з розміром за замовчуванням 512 b. Функція виконується після натискання клавіші Enter, після чого вводить 1 символ. Решта введені символи залишаються в буфері, чекаючи своєї долі. Макрос getchar аналогічний функції fgetchar. Функції getch і getche Прототипи: int getch (void); int getche (void); Повертають: символ, розширений до int без продовження знака. Опис. Функція getch виводить символ на монітор, getche - не виводить. Функції мають буфер на два символи: у разі натискання клавіші з розширеним кодом туди записується 0 і scan-код натиснутої клавіші. Не очікують натискання Enter. Буфер не очищається навіть при повторному запуску програми. Функція kbhit Прототип: int kbhit (void); Повертає: 1, якщо на момент виклику функції була натиснута, але не оброблена якась клавіша; 0-в іншому випадку. Опис. Функція залишає коди натиснутою клавіші в буфері введення-виведення з клавіатури, так що їх можна прочитати, наприклад, за допомогою getch. Функція ungetc Прототип: int ungetc (int d, FILE * stream); Повертає: символ d, посланий назад у вхідний потік stream, і EOF у разі помилки. Опис. Виштовхує символ d назад у вхідний потік stream. Повернути можна тільки один символ. Наступне читання з потоку поверне символ d. Символ з розширеним кодом повернути не вдасться. Функція ungetch Прототип: int ungetch (int d); Опис. Аналогічна ungetc, але виштовхує символ d назад в буфер клавіатури. Функція fgets Прототип: char * fgets (char * target, int n, FILE * stream); Опис. Вводить з stream не більше n символів в рядок за адресою target. Введення закінчується при зустрічі символу \ n. Повертає target при успішному введенні і NULL при зустрічі кінця файлу або у разі помилки. Функція gets Прототип: char * gets (char * target); Опис. Вводить з stdin рядок за адресою target. Число символів, що вводять не обмежена. В іншому схожа на fgets. Функція cgets Прототип: char * cgets (char * target); Опис. Читає рядок з консолі. str [0] повинно містити максимальну довжину вводиться рядка. Після закінчення str [l] містить число реально введених символів. Введена рядок починається з елемента str [2]. Для переходу на новий рядок у формат потрібно вставити два символи: \ n \ r. Повертає початок введеного рядка str [2]. Функція fputs Прототип: int fputs (const char * s, FILE * stream); Опис. Записує рядок в потік. Повертає останній записаний символ. Функція puts Прототип: int puts (const char * s); Опис. Записує рядок у потік stdout. Повертає останній записаний символ. Функція cputs Прототип: int cputs (const char * s); Опис. Записує рядок у текстове вікно на екрані. Повертає останній надрукований символ. Інші функції серії .. printf Прототипи: int fprintf (FILE * stream, const char * format [, argument ,...]); int cprintf (const char * format [, argument ,...]); int sprintf (char * buffer, const char * format [, argument ,...]); Опис. Функції пишуть відповідно в потік, у текстове вікно на екрані і в рядок. Повертають число реально виведених символів. Форматування відбувається так само, як для функції printf. Функції виводу на екран з conio.h Функція void clrscr (void) очищає екран. Для приміщення курсору в позицію (х, у) на екрані в текстовому режимі використовується функція void gotoxy (int х, int у). Для визначення координат курсору є функції int wherex () і int wherey (). За умовчанням текст має білий колір на чорному фоні. Щоб змінити колір тексту потрібно викликати функцію void textcolor (int newcolor), де newcolor приймає значення з перечислимого типу enum COLORS {BLACK, BLUE, GREEN, CYAN, RED, MAGENTA, BROWN, LIGHTGRAY, DARKGRAY, LIGHTBLUE, LIGHTGREEN, LIGHTCYAN, LIGHTRED, LIGHTMAGENTA, YELLOW, WHITE}; Колір можна задати його номером від 0 до 15. При цьому колір BLACK = 0 завжди означає колір фону. До кольору можна додати мерехтіння BLINK. Наприклад, textcolor (BLUE | BLINK); Кожен символ має свій фон, колір якого можна змінити функцією void textbackground (int newcolor). Інформацію на екрані можна переміщати прямокутними блоками за допомогою функції int movetext (int left, int top, int right, int bottom, int destleft, int desttop); Розмір текстового екрану можна змінити до розмірів бажаного текстового вікна: void window (int left, int top, int right, int bottom); При цьому лівий кут екрана має координати (1,1). Після переходу до текстового вікна система координат прив'язується до цього вікна. З текстовим вікном працюють функції: putch (), cputs, cprintf (), gotoxy (), wherex, wherey. Кордон вікна не малюється, але текст при виході з вікна буде скорочуватися. При досягненні правої межі відбувається автоматичний перехід на новий рядок, а при досягненні нижньої межі - вертикальний скролінг. Таким чином, текстове вікно має всі властивості текстового екрана. Текст може друкуватися на екрані яскравим або нормальним кольором. Для цього треба викликати відповідно функції void highvideo (void), void normvideo (). Ці установки впливають на всі наступні виклики функцій, пов'язаних із виведенням тексту на екран: putch (), cputs, cprintf (). Питання. Як дізнатися ascii-код певної клавіші? Відповідь. Найпростіше вставити в програму тимчасовий фрагмент типу char d = getch (); d = getch (); Потім подивитися в відладчик значення змінної d. Звичайно, можна написати і більш зручну програмку. # Include <conio.h> # Include <stdio.h> main () { char c, d; clrscr (); printf ("\ nНатисніть клавішу або комбінацію клавіш"); if (! (c = getch ())) { d = getch (); printf ("\ nРасшіренний код: 0,% i = '% c''', d, d); } else printf (["\ nAscci-код:% i = '% c''', з, с); if (! getch ()) getch (); } Питання. Як надрукувати на екрані графічне представлення керуючих символів. Відповідь: Друк керуючих символів реалізує їх функціональне призначення. Наприклад, символ Tab, що має код '\ t' = 9, рівносильний кільком прогалин. Так діють усі функції виведення. Для графічного подання подібних символів потрібно помістити їх код безпосередньо у відеобуфер. Для кольорового графічного адаптера відеобуфер починається з абсолютної адреси 0хВ80001. На символ відводиться 2 байти: перший - для asccii-коду, другий - для атрибутів. Цей метод називається відображенням на згадку. Рядки екрану розташовуються в буфері послідовно. # Include <conio.h> # Include <stdio.h> # Include <dos.h> void main () { char * pc = (char *) 0xB80000001 + 2 * (80 * (wherey ()-l) + wherex ()-l); pc [0] = '\ t'; pc [1] = 7; / / Звичайний атрибут / / Краще використовувати функцію запису за вказаною / / Адресою ОЗУ / / Poke (0xB800, 2 * (80 * (wherey ()-l) + wherex ()-l), 0x700 + / / 'А'); / / Числа типу int записуються в ОЗУ навпаки: дві / / Старші 16-е цифри - у молодшому (правом) байті, / / Молодші цифри - у старшому (лівому) байті if (! getch ()) getch (); } Практичні вправи З клавіатури вводиться текстова рядок російською мовою. Знайдіть кількість голосних і приголосних букв. Використовуйте фільтр для введення тільки текстових символів. Обчисліть відносну похибку правою формули для обчислення похідної деякої простої функції y = f (х):
у '= (f (x0 + eps) - f (x0)) / eps. Уявіть результати в табличній формі для збільшень eps, логарифм яких пробігає від -1 до -14 з кроком 0.1. Таблицю запишіть у файл. Речові числа мають тип float. Знайдіть оптимальне приріст. У файл записані упереміж текст і цілі числа. Знайдіть суму всіх чисел. Роздрукуйте на екрані таблицю множення для 16-х чисел. Роздрукуйте на екрані таблицю ASCII-кодів з графічним зображенням керуючих символів. Напишіть програму, яка запитує пароль. Невірний пароль зупиняє програму.
Лабораторні завдання Напишіть програму, що реалізовує всі можливості друкарської машинки:
з клавіатури безпосередньо на екран виводяться тільки символи, що є на друкарській машинці; перехід на новий рядок по натисненню Enter; переміщення курсору по екрану за допомогою стрілок; забій символу над курсором здійснюється пропуском.
Напишіть програму, яка малює в центрі зеленого екрану прямокутник розміром з чверть екрана. Межа області - жовта, колір заповнення блідо-синій, в центрі крана - мерехтливий текст червоного кольору. Напишіть функцію, яка отримує масив рядків, малює вікно з кордоном з одинарною рамки і вставляє рядки масиву по одній в це вікно. Розміри вікна - мінімально можливі. Напишіть функцію, що реалізовує меню з декількома виборами, в якому обираний пункт висвічується і переміщається за допомогою стрілок.
Бібліографічний список Джордейн Р. Довідник програміста персональних комп'ютерів типу IBM PC, XT і AT. М.: Фін. і стат., 1992. Керніган Б., Рітчі Д. Мова програмування Сі. М.: Фін. і стат., 1992. Керніган Б., Рітчі Д. Мова програмування Сі. Завдання за курсом Сі. М.: Фін. і стат., 1985. Уінер Р. Мова Турбо Сі. М.: Світ, 1991. Хікс К. Сі без проблем. Керівництво користувача. М.: Біном, 1997.
Додати в блог або на сайт
Цей текст може містити помилки. Програмування, комп'ютери, інформатика і кібернетика | Лабораторна робота 135.7кб. | скачати
Схожі роботи: Організація вводу виводу Пристрої вводу-виводу ПК Основи графічного виводу Пристрої виводу інформації 2 Використання багаторівневих та маркованих списків Методи вводу в текст багаторівневих та марков Засоби виводу інформації на принтер в обєктно-орієнтованому середовищі програмування Delphi Засоби виводу інформації на принтер в об єктно орієнтованому середовищі програмування Delphi Реалізація функцій бібліотеки графіки для виводу тексту у графічному режимі OutTextXY SetTextStyle 2 Реалізація функцій бібліотеки графіки для виводу тексту у графічному режимі OutTextXY SetTextStyle
|