Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Бичков - Основи сучасного програмування.doc
Скачиваний:
81
Добавлен:
07.03.2016
Размер:
3 Мб
Скачать
☆

6.9.2. Функції введення–виведення консольного термінала та порту

Функції введення–виведення консольного термінала та порту розширюють свої можливості для цього класу пристроїв, безпосередньо використовуючи їх специфіку (відеоадаптер тощо). Функції роботи з портом читають і записують дані побайтно. Деякі додаткові режими встановлюються відповідними функціями для консолі, наприклад введення з ехо-друком чи без, і специфічні для IBM PC. Розглянемо деякі функції:

 cgets() – читання рядка з консолі;

 cprintf() – аналог printf;

 cputs() – запис рядка на консоль;

 getch() – читання символу;

 getche() – читання символу з ехо-друком;

 kbhit() – перевірка натискання клавіші;

 putch() – запис символу на консоль;

 ungetch() – повернення останнього прочитаного символу з консолі для того, щоб він став наступним для читання;

 cscanf() – аналог scanf;

 getpass() – введення з термінала пароля без ехо-друку.

Консольний термінал і порт не можуть бути відкриті чи закриті перед виконанням введення-виведення, тому fopen та fclose не використовуються. Наприклад:

#include <conio.h>

Int main(void)

{

char*password;

password=getpass("Input a password:");

cprintf("The password is: %s\r\n",password);

return 0;

}

6.9.3. Функції введення–виведення нижнього рівня

Функції введення–виведення нижнього рівня не працюють із буферизованими чи форматованими даними. При роботі з файлами вони використовують дескриптори файлів. Основні функції:

 close() – закриття файла;

 creat() – створення;

 dup() – створює другий дескриптор файла;

 dup2() – перепризначує дескриптор файла;

 eof() – перевірка на кінець файла;

 lseek() – позиціювання файлового покажчика;

 open() – відкривання;

 read() – читання;

 sopen() – відкривання файла в режимі розділення;

 tell() – повертає поточну позицію покажчика;

 write() – запис.

Розглянемо програму:

#include <sys\stat.h>

#include <string.h>

#include <fcntl.h>

#include <io.h>

Int main(void)

{

Int handle;

char buf[11]="0123456789";

/*змінює режим відкривання файла з текстового на бінарний*/

_fmode=O_BINARY;

/*створює двійковий файл для читання та запису*/

handle=creat("DUMMY.FIL",S_IREAD |S_IWRITE);

/*записує 10 байтів у файл*/

write(handle,buf,strlen(buf));

/*закриває файл*/

close(handle);

return 0;

}

Розглянемо приклади розв'язання задач.

1. Написати програму, яка друкує номер і код введеного символу у вісімковому та шістнадцятковому вигляді.

#include <stdio.h>

Void main(void)

{char c;

printf("введіть символ\n');

scanf("%c',&c);

printf("номер десятковий:');

printf("%d\n',c-'0');

printf("номер вісімковий:');

printf("%o\n',c-'0');

printf("номер шістнадцятковий:');

printf("%x\n',c-'0');

printf("код десятковий:');

printf("%d\n',c);

printf("код вісімковий:');

printf("%o\n',c);

printf("код шістнадцятковий:');

printf("%x\n',c);

}

2. Підрахувати кількість символів вхідного потоку.

Розглянемо програму:

#include <stdio.h>

main()

{

long nc;

nc=0;

while (getchar()!=EOF)

++nc;

printf("%1d\n",nc);

}

Програма підрахунку символів накопичує їхню кількість у змінну типу long, а не int (максимальне число – 32767), і, якщо описати лічильник як int, то він буде переповнятися навіть при порівняно малому файлі. Специфікація перетворення %1d указує printf, що відповідний аргумент є цілим типу long.

Для роботи із більшими числами можна використовувати тип double. Ми використаємо оператор for замість while для того, щоб проілюструвати інший спосіб запису циклу:

main()

{ /*count characters in

*input*/

double nc;

for (nc=0;getchar()!=EOF; ++nc);

printf("%.0f\n",nc);

}

Функція printf використовує специфікацію %f як для float, так і для double; специфікація %.0f дозволяє не друкувати дробову частину.

Тіло оператора циклу for тут порожнє, тому що вся робота виконується в перевірочній та ініціювальній частинах. Якщо файл введення не містить жодних символів, то умова у while чи for не виконається при найпершому звертанні до getchar, і, отже, програма видасть нуль.

3. Підрахувати кількість рядків у файлі.

Вважатимемо, що рядок закінчується \n.

main()

{ /*count lines in input*/

int s,nl;

nl=0;

while ((s=getchar())!=EOF)

if (s=='\n')

++nl;

printf("%d\n",nl);

}

Тіло while тепер містить оператор if, який, у свою чергу, керує оператором інкремента ++nl. Оператор if перевіряє вкладену в круглі дужки умову і, якщо вона істинна, виконує оператор, що йде за ним.

4. Написати програму, що копіює символи вхідного файла у вихідний.

Загальна схема програми:

ввести символ

while (символ не є ознакою кінця файла)

вивести тільки що прочитаний символ

ввести новий символ

Текст програми:

#include <stdio.h>

main()

{/*copy input tо output;

*1st version*/

int c;

c=getchar();

while (c!=EOF) {

putchar(c);

c=getchar();

}

}

Основна проблема полягає в тому, щоб зафіксувати кінець файла. Коли функція getchar досягає кінця файла, вона повертає значення, що не є дійсним символом. Однак яке значення є ознакою кінця файла? Це може бути –1 чи 0, тому використовується символічне ім'я (макровизначення) EOF, яке визначається як

#define EOF -1

або

#define EOF 0

У цьому фрагменті змінна 'с' описана як int, а не char, для того, щоб вона могла зберігати значення, яке повертається getchar.

Цю програму можна написана більш стисло.

У мові C будь-яке присвоювання, наприклад

c=getchar();

може бути використане у виразі; його значенням є значення, що присвоюється лівій частині. Тоді програма копіювання файла запишеться у вигляді

main()

{/*copy input->output;

*2nd version*/

int c;

while((c=getchar())!=EOF)

putchar(c);

}

Програма отримує символ зі стандартного введення, присвоює його змінній 'с' і потім перевіряє, чи не є цей символ ознакою кінця файла. Якщо не є – виконується тіло оператора while, що виводить цей символ. Потім цикл while повторюється. Коли, нарешті, буде досягнутий кінець файла введення, оператор while завершується, а разом з ним закінчується виконання й функції main.

Важливо зрозуміти, що круглі дужки навколо присвоювання в умовному виразі дійсно необхідні. Пріоритет операції != вище, ніж операції присвоювання =, а це означає, що без круглих дужок перевірка умови != буде виконана до присвоювання =. Таким чином, оператор

c=getchar()!=EOF

еквівалентний оператору

c=(getchar()!=EOF)

5. Напишіть програму з використанням циклів, що створює трикутник:

*

***

*****

*******

*********

/*Трикутник із зірочок*/

#include <stdio.h>

/*Друк n символів c*/

printn(c,n){

while(--n>=0)

putchar(c);

}

int lines=10; /*кількість рядків трикутника*/

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]