Logo GenDocs.ru

Поиск по сайту:  

Загрузка...

Лекции по C/С++ - файл Л4.doc


Загрузка...
Лекции по C/С++
скачать (357.8 kb.)

Доступные файлы (8):

Л1.doc318kb.06.09.2009 15:02скачать
Л2.doc250kb.06.09.2009 14:56скачать
Л3.doc127kb.07.12.2009 15:34скачать
Л4.doc250kb.06.09.2009 14:57скачать
Л5.doc151kb.06.09.2009 14:58скачать
Л6.doc165kb.06.09.2009 14:58скачать
Л7.doc150kb.06.09.2009 14:58скачать
Л8.doc269kb.13.01.2006 20:00скачать

Л4.doc

Реклама MarketGid:
Загрузка...

Лекция №4

3. ФУНКЦИИ СТАНДАРТНОГО И ФОРМАТНОГО ВВОДА-ВЫВОДА

3.1. Основы ввода-вывода в языке С

Функции ввода-вывода можно разделить на 4 группы:

  1. функции посимвольного ввода-вывода, за одно обращение к которым переносится один символ;

  2. функции построчного ввода-вывода, за одно обращение к которым переносится ASCIIZ–строка символов;

  3. функции блокового ввода-вывода, за одно обращение к которым переносится целый блок(или запись) информации;

  4. функции форматированного ввода-вывода, при выполнении которых осуществляется присваивание значений переменным(ввод) или вывод представления переменных в поток.

Различают функции стандартного ввода-вывода, которые предназначены для ввода-вывода данных с клавиатуры. Кроме того отметим, что в стандартной библиотеке ввода/вывода некоторые "функции" на самом деле могут быть макросами. Это позволяет избежать накладных расходов на обращение к функции для обработки каждого символа. 

^

Обращение к стандартной библиотеке.


Каждый исходный файл, который обращается к функции из стандартной библиотеки, должен вблизи начала содержать строку

#include <stdio.h> или(и) #include <conio.h>

В файлах stdio.h и conio.h определяются некоторые макросы и переменные, используемые библиотекой ввода/вывода. Использование угловых скобок вместо обычных двойных кавычек - указание компилятору искать этот файл в справочнике, содержащем заголовки стандартной информации (на системе UNIX обычно lusrlinelude).



Самостоятельная проработка:



^

3.1.1. Функции посимвольного ввода-вывода

3.1.1.1.Функции посимвольного ввода


В случае успеха функции возвращают прочитанный символ после его преобразования в int без учета знака.

Функции возвращают значение EOF в случае ошибки или когда попадают на конец файла, какой бы ввод они при этом не считывали. Стандартная библиотека полагает символическую константу EOF равной -1 (посредством #define в файле stdio.h), но проверки следует писать в терминах EOF, а не -1, чтобы избежать зависимости от конкретного значения.

Функция

Назначение

^

#include <stdio.h>

int getchar(void);

Возвращает символ из файла стандартного ввода. Является макроопределением через функцию getc().

#include <stdio.h>

int _fgetchar(void);

Возвращает символ из файла стандартного ввода.


#include <stdio.h>
^

int fgetc(FILE *stream);

Возвращает символ из открытого файла, описываемого переменной типа FILE , на которую указывает stream .

^

#include <stdio.h>

int getc(FILE *stream);

Возвращает символ из открытого файла, описываемого переменной типа FILE , на которую указывает stream . Является макроопределением через функцию _fgetc().


#include <conio.h>

int getch(void);
^

Выполняет ввод символа с клавиатуры без эхо- отображения на экране.


#include <conio.h>

int getche(void);

Выполняет небуферизуемый ввод символа с клавиатуры с эхо- отображением на экране.


#include <conio.h>

int ungetch(int ch);
^

Записывает непосредственно в буфер клавиатуры символ ch.

#include <stdio.h>

int ungetc(int c, FILE *stream);

Возвращает символ int c назад в поток stream. Следующая операция чтения из файла stream будет возвращать символ c.


Функции посимвольного стандартного ввода
^

Функция getchar


Самый простой механизм ввода заключается в чтении по одному символу за раз из "стандартного ввода", обычно с терминала пользователя, с помощью функции getchar.

^ Форма записи:

#include <stdio.h>

int getchar(void);

Функция getchar() при каждом к ней обращении возвращает следующий вводимый символ. В большинстве сред, которые поддерживают язык С++, терминал может быть заменен некоторым файлом с помощью обозначения < : если некоторая программа prog использует функцию getchar то командная строка

prog < infile

приведет к тому, что prog будет читать из файла infile, а не с терминала. Переключение ввода делается таким образом, что сама программа prog не замечает изменения; в частности строка"<infile" не включается в командную строку аргументов в argv. Макро getchar идентична getc(stdin).

Пример:

#include <stdio.h>

int main(void)

{ char ch;

printf("Enter a character followed by <Enter>: ");

ch = getchar();

printf("The character read is: '%c'\n", ch);

return 0;

}

^ Функция fgetchar

Функция

#include <stdio.h>

int fgetchar(void);

читает отдельный текущий символ из стандартного потока stdin и увеличивает cсоответствующий указатель (если он есть) для указания следующего считываемого символа. Функция fgetchar является эквивалентной функции fgetc(stdin).

Пример:

#include <stdio.h>

int main(void)

{ char ch;

printf("Enter a character followed by <Enter>: ");

ch = fgetchar();

printf("The character read is: '%c'\n", ch);

return 0;

}

^ Функция ungetch

Функция

#include <conio.h>

int ungetch(int ch);

записывает непосредственно в буфер клавиатуры символ ch. Он будет доступен при выполнении следующей операции чтения с консоли (функциями файла <conio.h>). Разрешает помещать только один символ, который не может совпадать с константой EOF, описанной в файле <stdio.h>. В случае успеха функция возвращает ch; в противном случае возвращается -1.

Пример: Строка символ за символом помещается в буфер клавиатуры, затем читается и выводится на экран.

#include <stdio.h>

#include <conio.h>

#include <dos.h>

void main(void)

{ char *string="String of text";

while(*string)

{ ungetch(*string++);delay(200);

putchar(getch());}

}

^ Функция getch

Функция

#include <conio.h>

int getch(void);

выполняет ввод символа с клавиатуры без эхо- отображения на экране. В этой связи полезна для организации интерфейса с пользователем, при котором нажатие той или иной клавиши вызывает немедленную реакцию программы без отображения введенного символа на экране. Например, может использоваться в качестве задержки, пока не нажата любая клавиша.

^ Функция getche

Функция

#include <conio.h>

int getche(void);

выполняет небуферизуемый ввод символа с клавиатуры с эхо- отображением на экране. Перевод строки происходит при достижении правой вертикальной границы текущего активного окна.

Пример: программа иллюстрирует применение функций getch() и getche() для определения нажатий не только ASCII- клавиш, но и специальных клавиш.

#include <stdio.h>

#include <conio.h>

void main(void)

{ int ch;

do { puts("Нажмите любую клавишу...");

if(!(ch=getch()))

{ ch=getch();

printf("Специальная клавиша\

Расширенный скэн-код: %#u\n",ch);}

else printf("Символьная клавиша %c\

(Код %#u)\n",ch,ch);

puts("Продолжаете?(y/n)"); }

while((ch=getch())=='y'||ch=='Y');

}
^ Функции посимвольного потокового ввода
Функция fgetc

Функция

#include <stdio.h>

int fgetc(FILE *stream);

читает отдельный текущий символ из входного потока stream и увеличивает cсоответствующий указатель (если он есть) для указания следующего считываемого символа.

Пример:

#include <string.h>

#include <stdio.h>

#include <conio.h>

int main(void)

{

FILE *stream;

char string[] = "This is a test";

char ch;

stream = fopen("DUMMY.FIL", "w+");

fwrite(string, strlen(string), 1, stream);

fseek(stream, 0, SEEK_SET);

do

{

ch = fgetc(stream);

putch(ch);

} while (ch != EOF);

fclose(stream);

return 0;

}

^ Функция getc

Функция

#include <stdio.h>

int getc(FILE *stream);

читает отдельный символ из текущей позиции потока stream и изменяет соответствующий указатель на файл для указания следующего символа.

Пример:

#include <stdio.h>

int main(void)

{

char ch;

printf("Input a character:");

ch = getc(stdin);

printf("The character input was: '%c'\n", ch);

return 0;

}

^ Функция ungetc

Функция

#include <stdio.h>

int ungetc(int c, FILE *stream);

возвращает символ c в заданный поток ввода stream. Stream должен быть буферизованным и открытым для чтения. Последующая операция чтения из stream начинается с символа c. EOF вернуть в поток посредством использования ungetc нельзя. Эта функция возвращает значение ошибки, если из stream ничего не прочитано или если c назад не возвращен. Символы, размещаемые в потоке посредством ungetc, могут быть уничтожены, если функции fseek или rewind вызваны перед считыванием символа из stream.

Пример:

#include <stdio.h>

#include <ctype.h>

int main( void )

{

int i=0; char ch;

puts("Input an integer followed by a char:");

while((ch = getchar()) != EOF && isdigit(ch))

i = 10 * i + ch - 48; /* convert ASCII into int value */

if (ch != EOF) ungetc(ch, stdin);

printf("i = %d, next char in buffer = %c\n", i, getchar());

return 0;

}
^

3.1.1.2. Функции посимвольного вывода

Функция

Назначение

#include <stdio.h>

int fputchar(int c);

Помещает символ в файл стандартного вывода stdout

^

#include <stdio.h>

int putchar(int c);

Помещает символ в файл стандартного вывода stdout. Является макроопределением через функцию putc().

^

#include <stdio.h>

int putc(int c, FILE *stream);

Помещает символ в открытый файл, описываемый переменной типа FILE, на которую указывает fp. Является макроопределением через функцию _fputc().

^

#include <stdio.h>

int fputc(int c, FILE *stream);

Помещает символ в открытый файл, описываемый переменной типа FILE, на которую указывает fp.


#include <conio.h>

int putch(int c);

Выводит символ в текущей позиции текстового окна экрана.

Функции стандартного вывода

Функция putchar


Вывод можно осуществлять с помощью функции putchar(c).

^ Форма записи:

#include <stdio.h>

int putchar(int c);

функции putchar(c) помещает символ 'c' в "стандартный ввод", который по умолчанию является терминалом. Вывод можно направить в некоторый файл с помощью обозначения > : если prog использует putchar, то командная строка

prog > outfile

приведет к записи стандартного вывода в файл outfile, а не на терминал.

Вывод, осуществляемый функцией printf, также поступает в стандартный вывод, и обращения к putchar и printf могут перемежаться.

Пример:

#include <stdio.h>

main()

{ char c;

c=getchar();

putchar(c);

printf(“%d”,c);

}

Результат:

а

а224

В данном примере показано неявное приведение типа char в тип int, в результате значение переменной с=’а’ преобразовывается в код этого символа, который равен 224.
^ Функция fputchar

Функция

#include <stdio.h>

int fputchar(int c);

записывает отдельный символ с в текущую позициюстандартного выходного потока. Функция putchar идентична функции putc(c, stdout).Функция putchar идентична fputchar, но является макро, а не функцией.

^ Функция putch

Функция

#include <conio.h>

int putch(int c);

выводит символ в текущей позиции текстового окна экрана. Воздействие спецсимвола ‘\n’ аналогично cprintf() и cputs() . Остальные спецсимволы воздействуют на курсор так же, как и для функции стандартного ввода/вывода.


^ Функции потокового вывода
Функция putc

Функция

#include <stdio.h>

int putc(int c, FILE *stream);

записывает отдельный символ с в текущую позицию выходного потока stream. Функция putc идентична fputc , но является макро, а не функцией.
Функция fputc

Функция

#include <stdio.h>

int fputc(int c, FILE *stream);

записывает отдельный символ с в текущую позицию выходного потока stream.


^

3.1.2.Форматированный ввод-вывод


Функция

Назначение

Функции ввода

#include <stdio.h>

int scanf(const char *format[, address, ...]);

Выполняет ввод с клавиатуры c буферизацией символов ввода.

#include <conio.h>

int cscanf(char *format[, address, ...]);

Выполняет ввод с клавиатуры без буферизации символов ввода.

Функции вывода

#include <stdio.h>

int printf(const char *format[, argument, ...]);

Выполняет вывод с преобразованием по заданному формату, возвращает число обработанных полей.

#include <conio.h>

int cprintf(const char *format[, argument, ...]);

Выполняет вывод с преобразованием по заданному формату, возвращает число выведенных байтов

^

3.1.2.1.Форматированный ввод

Функция scanf


Осуществляющая ввод функция scanf является аналогом printf и позволяет проводить в обратном направлении многие из тех же самых преобразований. Функция

Форма записи:

#include <stdio.h>

int scanf(const char *format[, address, ...]);

упрощенно

scanf(УправляющаяСтрока, arg1, arg2, ...)

Функция scanf читает символы из стандартного ввода, интерпретирует их в соответствии с форматом, указанном в форматной (или управляющей) строке, и помещает результаты в остальные аргументы. Управляющая строка описывается ниже; другие аргументы, каждый из которых должен быть указателем, определяют, куда следует поместить соответствующим образом преобразованный ввод. Управляющая строка обычно содержит спецификации преобразования, которые используются для непосредственной интерпретации входных последовательностей.
^

Функция cscanf


Функция

int cscanf(char *format[, address, ...]);

упрощенно

cscanf(УправляющаяСтрока, arg1, arg2, ...)

выполняет форматированный ввод с клавиатуры с эхо- отображением. В отличие от функции scanf() не выполняет буферизацию символов ввода: все символы, вводимые с клавиатуры, доступны программе немедленно. Ввод пробела рассматривается как завершение ввода.
^

Управляющая строка функций ввода


Управляющая строка может содержать:

  • пробелы, табуляции или символы новой строки ("символы пустых промежутков"), которые игнорируются.

  • Обычные символы (не %), которые предполагаются совпадающими со следующими отличными от символов пустых промежутков символами входного потока.

  • Спецификации преобразования, состоящие из символа %, необязательного символа подавления присваивания *, необязательного числа, задающего максимальную ширину поля и символа преобразования.

Спецификация преобразования управляет преобразованием следующего поля ввода. Нормально результат помещается в переменную, которая указывается соответствующим аргументом. Если, однако, с помощью символа * указано подавление присваивания, то это поле ввода просто пропускается и никакого присваивания не производится. Поле ввода определяется как строка символов, которые отличны от символов простых промежутков; оно продолжается либо до следующего символа пустого промежутка, либо пока не будет исчерпана ширина поля, если она указана. Отсюда следует, что при поиске нужного ей ввода, функция scanf будет пересекать границы строк, поскольку символ новой строки входит в число пустых промежутков.

Символ преобразования определяет интерпретацию поля ввода; согласно требованиям основанной на вызове по значению семантики языка С++ соответствующий аргумент должен быть указателем. Допускаются следующие символы преобразования.

Модификатор

  • (l) Модификатор длины l, который указывает, что соответствующий элемент данных имеет тип long, а не int.

  • (h) Модификатор длины h, который указывает, что соответствующий элемент данных имеет тип short, а не int.

  • (F) Аргумент рассматривается как far–указатель.

  • (N) Аргумент рассматривается как near–указатель.

^ Символы преобразования и их смысл

Тип переменной int

d на вводе ожидается десятичное целое; соответствующий аргумент должен быть указателем на целое.

o на вводе ожидается восьмеричное целое (с лидирующим нулем или без него); соответствующий аргумент должен быть указателем на целое.

x на вводе ожидается шестнадцатеричное целое (с лидирующими 0х или без них); соответствующий аргумент должен быть указателем на целое. При вводе нет различия между х и Х.

u аргумент преобразуется в беззнаковую десятичную форму - тип unsigned int.

Тип переменной char

c ожидается отдельный символ; соответствующий аргумент должен быть указателем на символы; следующий вводимый символ помещается в указанное место. Обычный пропуск символов пустых промежутков в этом случае подавляется; для чтения следующего символа, который не является символом пустого промежутка, пользуйтесь спецификацией преобразования %1s.

Тип переменной char*

s ожидается символьная строка; соответствующий аргумент должен быть указателем символов, который указывает на массив символов, который достаточно велик для принятия строки и добавляемого в конце символа \0.

Тип переменной float

f ожидается число с плавающей точкой; соответствующий аргумент должен быть указателем на переменную типа float.

e(E) символ преобразования е(E) является синонимом для f. Формат ввода переменной типа float включает необязательный знак, строку цифр, возможно содержащую десятичную точку и необязательное поле экспоненты, состоящее из буквы е(E), за которой следует целое, возможно имеющее знак. При вводе нет различия между е и Е.

g(G) используется или формат %е(или E) или %f(или F), какой короче; незначащие нули не печатаются. Если идущий за % символ не является символом преобразования, то печатается сам этот символ; следовательно, символ % можно напечатать, указав %%. При вводе нет различия между g и G.

Например, обращение

int 1;

float x;

char name[50];

scanf("%d %f %s", &i, &x, name);

со строкой на вводе

25 54.32e-1 thompson

приводит к присваиванию i значения 25, x - значения 5.432 и name - строки "thompson", надлежащим образом законченной символом \ 0. Эти три поля ввода можно разделить столькими пробелами, табуляциями и символами новых строк, сколько вы пожелаете. Обращение

int i;

float x;

char name[50];

scanf("%2d %f %*d %2s", &i, &x, name);

с вводом

56789 0123 45a72

присвоит i значение 56, x - 789.0, пропустит 0123 и поместит в name строку "45". При следующем обращении к любой процедуре ввода рассмотрение начнется с буквы а. В этих двух примерах name является указателем и, следовательно, перед ним не нужно помещать знак &.

#include <stdio.h>

main() /* rudimentary desk calculator */

{

double sum, v;

sum =0;

while (scanf("%lf", &v) !=EOF)

printf("\\t%.2f\n", sum += v);

}

Выполнение функции scanf заканчивается либо тогда, когда она исчерпывает свою управляющую строку, либо когда некоторый элемент ввода не совпадает с управляющей спецификацией. В качестве своего значения она возвращает число правильно совпадающих и присвоенных элементов ввода. Это число может быть использовано для определения количества найденных элементов ввода. При выходе на конец файла возвращается EOF; подчеркнем, что это значение отлично от 0, что следующий вводимый символ не удовлетворяет первой спецификации в управляющей строке. При следующем обращении к scanf поиск возобновляется непосредственно за последним введенным символом.

Пример:

P=scanf(“%d %d %f”,&i,&j,&k);

Если данные введены верно и нет сбоя( например, из-за введенного значения несоответствующего типа), то результат Р=3.

Заключительное предостережение: аргументы функции scanf должны быть указателями. Несомненно, наиболее распространенная ошибка состоит в написании

scanf("%d", n);

вместо scanf("%d", &n);
^

3.1.2.2.Форматированный вывод

Функция printf


Две функции: printf для вывода и scanf для ввода (следующий раздел) позволяют преобразовывать численные величины в символьное представление и обратно. Они также позволяют генерировать и интерпретировать форматные строки

^ Форма записи:

#include <stdio.h>

int printf(const char *format[, argument, ...]);

или упрощенно

printf(УправляющаяСтрока, arg1, arg2, ...)

Функция преобразует, определяет формат и печатает свои аргументы в стандартный вывод под управлением форматной (или управляющей) строки. Управляющая строка содержит два типа объектов: обычные символы, которые просто копируются в выходной поток, и спецификации преобразований, каждая из которых вызывает преобразование и печать очередного аргумента printf.

Каждая спецификация преобразования начинается с символа % и заканчивается символом преобразования. Спецификация преобразования состоит из отдельных полей:

%[флаг][ширина] [. точность ][F|N|h|l ] <символ типа преобразования>
^ Функция cprintf

Функция

#include <conio.h>

int cprintf(const char *format [, arg, ...]);

выполняет вывод с преобразованием по заданному формату. Является аналогом функции стандартной библиотек printf(), но вывод осуществляется в пределах заданного окна. В отличие от printf() функция сprintf() иначе реагирует на специальный символ ‘\n’: курсор переводится на новую строку, но не возвращается к левой границе окна. Поэтому для перевода курсора на начало новой строки текстового окна надо вывести последовательность символов перевода каретки и перехода на следующую строку CR-LF (0х0d, 0x0a) или '\r\n’. Остальные спецсимволы воздействуют на курсор так же, как и для функции стандартного ввода/вывода. Функция возвращает число выведенных байтов, а не число обработанных полей, как это делает функция printf().

Пример: Вывести на экран 5 раз строку "This is a test".

#include <conio.h>

int main(void)

{ int i;

clrscr();

for (i=0; i<5; i++)

cprintf("This is a test\r\n");

}

^ Отдельные поля спецификации преобразования

Флаги

  • (-) Знак минус, который указывает о выравнивании преобразованного аргумента по левому краю его поля. Правая сторона выделенного поля дополняется пробелами.

  • (+) Знак плюс указывает, что выводится знак числа «-» или «+».

  • (Пробел) Выводится пробел перед числом, если оно положительно. Для отрицательных чисел знак «-» выводится всегда.

  • (#) Выводится идентификатор системы счисления для целых чисел:

-0 перед числом, выводимым в восьмеричной системе счисления;

-0х или 0Х для чисел, выводимых в шестнадцатеричной с/с;

-ничего для чисел, выводимых в десятичной с/с.

Ширина

  • (n или 0n)Строка цифр, задающая минимальную ширину поля n. Преобразованное число будет напечатано в поле по крайней мере этой ширины, а если необходимо, то и в более широком. Если преобразованный аргумент имеет меньше символов, чем указанная ширина поля, то он будет дополнен слева (или справа, если было указано выравнивание по левому краю) заполняющими символами до этой ширины. Заполняющим символом обычно является пробел, а если ширина поля указывается с лидирующим нулем, то этим символом будет нуль (лидирующий нуль в данном случае не означает восьмеричной ширины поля).

Точность

  • (.)Точка, которая отделяет ширину поля от следующей строки цифр.

  • (.0)Для d, i, o, u, x точность по умолчанию. Для e, E, f десятичная точка отсутствует.

  • (.nnn) Строка цифр (точность), которая указывает максимальное число символов строки, которые должны быть напечатаны, или число печатаемых справа от десятичной точки цифр для переменных типа float или double. По умолчанию точность равна 6.

Модификатор

  • (l) Модификатор длины l, который указывает, что соответствующий элемент данных имеет тип long, а не int.

  • (h) Модификатор длины h, который указывает, что соответствующий элемент данных имеет тип short, а не int.

  • (F) Аргумент рассматривается как far–указатель.

  • (N) Аргумент рассматривается как near–указатель.

Пример:

Р=15.6734;

По умолчанию данное число принимает вид:

Р=15.673400 (количество символов после десятичной точки по умолчанию равно 6)

12 – Результат: 1 5 . 6 7 3 4 0 0

.12– Результат: 15. 6 7 3 4 0 0 0 0 0 0 0 0

12 .– Результат 1 6 (Если дробная часть <=5, то округляется в сторону уменьшения, а если >5 - в сторону увеличения)

12 .2– Результат: 1 5 . 6 7

Символы преобразования и их смысл

Тип переменной int

d аргумент преобразуется к десятичному виду(тип int) со знаком.

i аргумент преобразуется к десятичному виду(тип int) со знаком.

o аргумент преобразуется в беззнаковую восьмеричную форму (без лидирующего нуля) - тип unsigned int.

x аргумент преобразуется в беззнаковую шестнадцатеричную форму (без лидирующих 0х) - тип unsigned int. При выводе используются символы 0 – f.

^ X аргумент преобразуется в беззнаковую шестнадцатеричную форму (без лидирующих 0X) - тип unsigned int. При выводе используются символы 0 – F.

u аргумент преобразуется в беззнаковую десятичную форму - тип unsigned int.

Тип переменной char

c аргумент рассматривается как отдельный символ.

Тип переменной char*

s аргумент является строкой: символы строки печатаются до тех пор, пока не будет достигнут нулевой символ или не будет напечатано количество символов, указанное в спецификации точности.

Тип переменной float

f аргумент, рассматриваемый как переменная типа float или double, преобразуется в десятичную форму в виде [-]mmm.nnnnn, где длина строки из n определяется указанной точностью. Точность по умолчанию равна 6. Отметим, что эта точность не определяет количество печатаемых в формате f значащих цифр.

e аргумент, рассматриваемый как переменная типа float или double, преобразуется в десятичную форму в виде [-]m.nnnnnne[+-]хх, где длина строки из n определяется указанной точностью. Точность по умолчанию равна 6.

E аргумент, рассматриваемый как переменная типа float или double, преобразуется в десятичную форму в виде [-]m.nnnnnnE[+-]хх, где длина строки из n определяется указанной точностью. Точность по умолчанию равна 6.

g используется или формат %е или %f, какой короче; незначащие нули не печатаются. Если идущий за % символ не является символом преобразования, то печатается сам этот символ; следовательно, символ % можно напечатать, указав %%.

G используется или формат %E или %F, какой короче; незначащие нули не печатаются. Если идущий за % символ не является символом преобразования, то печатается сам этот символ; следовательно, символ % можно напечатать, указав %%.

Примеры:

int x;

float y;

x=78;

y=98.56;

printf("Действительные числа -\n %12f\n %-12f\n %12.f\n",y,y,y);

printf("Действительные числа -\n %f\n %.4f\n %e\n",y,y,y);

printf("Целые -\n %d\n %o\n %u\n %x\n",х,x,x,x);

Результат:

Действительные числа –

98.559998

98.559998

99

Действительные числа –

98.559998

98.5600

9.856000e+1

Целые –

78

116

78

4e

Большинство из форматных преобразований очевидно и было проиллюстрировано в предыдущих главах. Единственным исключением является то, как точность взаимодействует со строками. Следующая таблица демонстрирует влияние задания различных спецификаций на печать "hello, world" (12 символов). Мы поместили двоеточия вокруг каждого поля для того, чтобы вы могли видеть его протяженность.

:%10s: :hello, world:

:%-10s: :hello, world:

:%20s: : hello, world:

:%-20s: :hello, world :

:%20.10s: : hello, wor:

:%-20.10s: :hello, wor :

:%.10s: :hello, wor:

Предостережение: printf использует свой первый аргумент для определения числа последующих аргументов и их типов. Если количество аргументов окажется недостаточным или они будут иметь несоответственные типы, то возникнет путаница и вы получите бессмысленные результаты.



Самостоятельная проработка:


3.1.3. Функции построчного ввода-вывод


Функция

Назначение

Функции ввода

#include <conio.h>

char *cgets (char *str);

Помещает в буфер, на начало которого указывает str, строку символов из стандартного ввода.


#include <stdio.h>

char *gets(char *s);




#include <stdio.h>

char *fgets(char *s, int n, FILE *stream);




Функции вывода

#include <conio.h>

int cputs(const char *str);

Выводит строку символов в текстовое окно, начиная с текущей позиции курсора.

#include <stdio.h>

int puts(const char *s);




#include <stdio.h>

int fputs(const char *s, FILE *stream);





^ 3.1.3.1.Функции построчного ввода
Функция cgets

Функция

#include <conio.h>

char *cgets (char *str);

читает строку символов прямо с консоли и запоминает строку и ее длину в местоположении, указанном str. Str должно быть указателем на массив символов. Первый элемент массива - str[0] должен содержать максимальную длину (в символах) читаемой строки, во втором элементе массива str[1] запоминает действительную длину строки. Строка запоминается, начиная с str[2].

Массив должен быть достаточно большим, чтобы содержать строку, символ окончания '\0' и два дополнительных байта. Функция cgets продолжает считывать символы, пока не будет прочитан символ CR или определенное количество символов.

Если символ CR прочитан, перед запоминанием он заменяется нулевым символом '\0'.

Достоинства функции cgets:

  1. возможность определения при вводе длины строки;

  2. защита при вводе от «лишних» символов, для которых компилятором не зарезервировано место;

  3. возможность ввода за одно обращение к функции строк, длина которых превышает установленный по умолчанию буфер для стандартного ввода в 128 символов.

Пример: Ввод строки до 254 символов и вывод на экран реального размера введенной строки.

#include <stdio.h>

#include <conio.h>

void main(void)

{

char str[256];

str[0]=254;

cgets(str);

printf("Введено %d символов \

строки %s\n",str[1],&str[2]);

}

^ 3.1.3.2.Функции построчного вывода
Функция cputs

Функция

#include <conio.h>

int cputs(const char *str);

выводит строку символов, оканчивающуюся нулевым символом и на которую указывает str, в текстовое окно, начиная с текущей позиции курсора. Является аналогом функции стандартной библиотеки puts(), но выполняет вывод в пределах заданного окна и при выводе не добавляет специальный символ ‘\n’. Реакция cputs() на спецсимвол ‘\n’ аналогична реакции cprintf(): курсор переводится на новую строку, но не возвращается к левой границе окна. Поэтому для перевода курсора на начало новой строки текстового окна надо вывести последовательность символов CR-LF (0х0d, 0x0a) или добавить символ перевода каретки '\r’. Остальные спецсимволы воздействуют на курсор так же, как и для функции стандартного ввода/вывода. Функция возвращает ASCII- код последнего выведенного на экран символа. В отличие от puts() в функции отсутствует возврат символа EOF. Другими словами, вывод происходит на экран в любом случае, т.е. отсутствует вывод в файл.



^

Лекция №2(продолжение)

4. Основы ввода-вывода в С++

4.1. Библиотека iostream


Библиотека iostream (определенная в файле iostream.h) содержит два параллельных семейства классов: классы, которые являются производными (порожденными) из streambuf, и классы, производные из ios. Оба эти классы являются классами нижнего уровня, и каждый из них выполняет различный набор задач. Один из этих двух классов является базовым классом для всех классов потоков.
^

Буферизованные потоки (класс streambuf )


Класс streambuf обеспечивает общие методы буферизации и обработки потоков при небольшом объеме или отсутствии форматирования. streambuf это полезный базовый класс, используемый другими частями библиотеки iostream, хотя также вы можете создавать производные от него классы для собственных функций и библиотек. Классы strstreambuf, stdiobuf и filebuf являются производными от streambuf.

Класс streambuf управляет низкоуровневым буферизованным вводом, обеспечивая интерфейс с памятью и физическими устройствами.

Класс filebuf предназначен для управления буферами дисковых файлов(файл FSTREAM.H)

Класс strstreambuf предназначен для управления строковыми буферами, хранящимися в памяти (файл STRSTREA.H)

Класс stdiobuf осуществляет буферизацию дискового ввода-вывода с помощью стандартных системных функций (файл STDIOSTR.H)



Самостоятельная проработка:


^

Потоковый класс ios


Класс ios (и следовательно, производные от него классы) содержит указатель на streambuf.

Классы семейства ios предоставляют программный интерфейс и обеспечивают необходимое форматирование при вводе-выводе обрабатываемых данных, а непосредственную обработку данных выполняют классы семейства streambuf, управляющие обменом данными между буфером потока и конечным устройством.

Например, класс ifstream является производным от istream и fstreambase, а класс istrstream является производным от istream и strstreambase. Поскольку имеет место множественное наследование, данная схема показывает не просто иерархию классов. При множественном наследовании один класс может наследовать от нескольких базовых классов. Это означает, например, что все элементы (данные и функции) iostream, istream, ostream, fstreambase и ios являются частью объектов класса fstream. Все классы в сети ios используют streambuf (либо filebuf или strstreambuf, которые представляют собой специальные случаи streambuf) в качестве источника и/или приемника.


^

4.2. Стандартные потоки cin, cout и cerr

Стандартным потокам языка С stdin, stdout и stderr, объявленным в файле STDIO.H, в С++ соответствуют объекты-потоки cin, cout, cerr и clog, подключаемые посредством файла IOSTREAM.H.

^

cin объект класса istream, связанный со стандартным потоком ввода

cout объект класса ostream, связанный со стандартным потоком вывода

^

cerr объект класса ostream, не поддерживающий буферизацию и связанный со стандартным потоком ошибок

clog объект класса ostream, поддерживающий буферизацию и связанный со стандартным потоком ошибок

^

4.2.1. Потоковый вывод


Потоковый вывод выполняется с помощью операции включения (или помещения)<<. Стандартная операция сдвига влево << для операций вывода переопределяется. Ее левый операнд - это объект типа ostream, а правый операция может иметь любой стандартный тип, т.к. оператор << перегружен таким образом, чтобы поддерживать все стандартные типы данных. Операция << ассоциируется слева направо и возвращает ссылку на объект ostream, для которого она вызывается. Это позволяет выполнять каскад операций. Пример:

printf(“ Целое число:%d ,число с плавающей точкой: %f”,i,f);

заменяется в С++ на

cout<<”Целое число:”<<i<<”,число с плавающей точкой: ”<<f;
^

Оператор << самостоятельно анализирует тип данных и выбирает формат их представления.




Самостоятельная проработка:


^

Перегрузка оператора <<


Допускается перегружать данный оператор. Прямым следствием перегрузки является возможность расширения операторов << и>> для обработки данных нестандартных типов. Ниже показано, как перегрузить оператор вывода, чтобы он мог принимать данные нового типа tclient:

struct tclient {char pszname[25]; char pszaddress[30];int pszphone;}

ostream& operator << (ostream& osout, tclient client)

{ osout<<” “<< client.pszname;

osout<<” “<< client.pszaddress;

osout<<” “<< client.pszphone;

}

Теперь для вывода содержимого структуры client необходимо задать следующий оператор:

cout<<client;
^

Эффективность операторов << и >> объясняется компактностью их программного кода.



4.2.2. Потоковый ввод


Потоковый ввод использует переопределенную операцию сдвига вправо, >>, и называется операцией извлечения, или извлечением. Левый операнд операции >> представляет собой объект типа класса istream. Как и для вывода, правый операнд может быть любого типа, для которого определен вывод потоком.

Пример:

scanf(“%d%f%c”,&i,&f,&c);

заменяется на

cin>>i>>f>>c;

Нет необходимости при вводе данных ставить перед именами переменных оператор взятия адреса &,т.к. в С++ оператор >> вычисляет адрес, определяет формат и прочие особенности записи значения переменной.

Рассмотрим еще один пример:

int i;

double d;

cin >> i >> d;

Последняя строка вызывает пропуск пробельных символов. Цифры, считываемые со стандартного устройства ввода (по умолчанию это клавиатура), преобразуются затем во внутренний двоичный формат и записываются в переменную i. Затем снова пропускаются пробельные символы, и наконец считывается число с плавающей точкой, которое преобразуется и записывается в переменную d.

Для типа char* (рассматриваемого как строка) действие операции >> состоит в пропуске пробельных символов и записи следующих (не пробельных) символов до тех пор, пока не встретится следующий пробельный символ. Затем добавляется завершающий нулевой (0) символ.

Для типа char (signed или unsigned) действие операции >> состоит в пропуске пробельных символов и записи следующего (не пробельного) символа.



Самостоятельная проработка:


Перегрузка оператора >>

Вы можете создавать извлечения для определенных вами типов таким же образом, как это делается со вставками. Используя информацию о структуре, определенной выше, операция >> может быть перегружена следующим образом:

struct info{char name; int val; float units;}

istream& operator >> (istream& s, info& m);

{

s >> m.name >> m.val >> m.units;

return s;

}

В реальных прикладных программах, разумеется, вы можете добавить коды для проверки ошибок ввода. Для считывания строки ввода, такой как "capacity 1.25 liters", можно использовать следующую запись:

cin >> m;

Пример:

struct tclient {char pszname[25]; char pszaddress[30];int pszphone;}

istream& operator >> (istream& isin, tclient client)

{ isin>>client.pszname;

isin>>client.pszaddress;

isin>>client.pszphone;

}


^

4.3. Форматирование потокового ввода-вывода


Существует три способа управления форматом выходных данных: использование флагов, вызов форматирующих функций-элементов, применение манипуляторов.

^ 4.3.1. Форматирующие функции-элементы

Для чтения и установки ширины поля потока в классе ios имеется функция width:

int ios::width();

int ios::width(int);

В первом случае функция возвращает текущее значение внутренней переменной ширины поля потока (по умолчанию оно равно нулю), а во втором устанавливает значение этой внутренней переменной.

Если функция используется при вводе, то она задает максимальное число читаемых символов, а если при выводе, то задает минимальную ширину поля. Если при выводе ширина поля меньше заданной, то выход дополняется символами, установленными fill. Если поле выводимого числа больше указанного, значение width игнорируется. После каждого помещения данных в поток значение функции обнуляется.

Пример:

#include<iostream.h>

void main()

{ const m=5;

char name[m];

cout<<”Введите имя: ”<<endl;

cin.width(m); cin>>name;

cout<<”Привет, ”<<name<<’!’;

}

Результат:

Введите имя:

Андрей

Привет, Андре!

Для чтения или изменения текущего заполняющего символа можно применять функцию ios::fill:

char ios::fill();

char ios::fill(char);

В первом случае функция возвращает текущее значение символа заполнения (по умолчанию пробел), а во втором – устанавливает заполняющий символ потока и возвращает его предыдущее значение.

Пример:

#include<iostream.h>

void main()

{int x=123;

cout.fill(‘*’); cout.width(6);

cout<<x;

}

Результат:

***123

Для чтения и установки числа значащих цифр при выводе чисел с плавающей точкой используется функция ios::precision:

int ios::precision();

int ios::precision(int);

В первом случае функция возвращает текущее значение точности (по умолчанию точность равна шести), а во втором случае – устанавливает внутреннюю переменную точности вещественных чисел потока и возвращает прежнее значение.

Если установлен флаг scientific или fixed, то precision задает число цифр, выводимых после десятичной точки, иначе задает общее число значащих цифр.
^ 4.3.2. Флаги форматирования

Форматирование ввода и вывода определяется различными флагами состояний формата, перечисленными в классе ios. Эти состояния определяются битами числа типа long int (см. таблицу) Эти флаги читаются функцией-элементом flags, устанавливаются функцией setf() и сбрасываются функцией unsetf(). Есть два варианта функции setf():

long ios::setf(long);

long ios::setf(long, long);

Первым аргументом является набор флагов, объединенных операцией побитового ИЛИ(|) (см. таблицу). Вторым аргументом является специальная битовая маска, определяющая, какую группу флагов можно модифицировать(изменять):

Для чтения и установки текущих флагов потока используется функция:

long ios::flags();

long ios::flags(long);

В первом случае функция возвращает текущие флаги потока, а во втором – присваивает флагам значение, сообщаемое параметром, и возвращает прежнее значение флагов.

adjustfield = internal | left | right

basefield = dec | oct | hex

floatfield = fixed | scientific

Пропуск пробельных символов управляется флагом ios::skipws в перечислимой переменной состояния. Флаг skipws обычно устанавливает пропуск пробельных символов. Очистка этого флага (например, при помощи setf) выключает пропуск пробельных символов. Отметим также специальный манипулятор "приемника", ws, который позволяет игнорировать пробельные символы.

Таблица ^ Флаги форматирования

Флаг

Бит числа

Назначение

skipws

0x0001

пропуск пробельного символа на вводе

left

0x0002

вывод с левым выравниванием

right

0x0004

вывод с правым выравниванием

internal


0x0008


заполнитель после знака или указателя системы счисления (знак числа выводится с левого края, а число – с правого, остальное заполняется символами fill)

dec

0x0010

десятичное преобразование

oct

0x0020

восьмеричное преобразование

hex

0x0040

шестнадцатеричное преобразование

showbase

0x0080

показать на выходе указатель системы счисления

showpoint

0x0100

показать позицию десятичной точки(на выходе)

uppercase


0x0200


вывод шестнадцатеричных значений буквами верхнего регистра (экспонента также Е)

showpos

0x0400

показать знак "+" для положительных чисел

scientific


0x0800


использовать запись чисел с плавающей точкой с выводом экспоненты Е например, 12345E2

fixed

0x1000

использовать запись чисел с плавающей точкой типа 123.45

unitbuf

0x2000

буфер потока опорожняется после каждой операции помещения

stdio

0x4000

потоки stdout и stderr опорожняются после каждой операции помещения
^

Пример: Вывести на экран таблицу квадратов и квадратных корней чисел от 1 до 5.

#include <iostream.h>

#include <math.h>

main()

{ double n=1.0,kv,kvk ;

cout<<" число\tквадрат\t\tкорень квадратный\n";

cout<<"_________________________________________\n";

cout.setf(ios::fixed); //фиксированный формат(без экспоненты)

^

for(int i=0;i<=5;i++)

{

kv=n*n;

kvk=sqrt(n);

cout.fill('0'); cout.width(2);

cout. precision(0); //0 цифр после запятой

cout<<n<<'\t';

^

cout.fill(' '); cout<<kv<<"\t\t";

cout. precision(6); cout<<kvk<<'\n';

n++;

}

}

Результат:

число квадрат корень квадратный

_____________________________________

01 1 1.000000

02 4 1.414214

^

03 9 1.732051

04 16 2.000000

05 25 2.236068

4.3.3. Манипуляторы


Простой способ изменения некоторых форматных переменных состоит в использовании специальной функциональной операции, которая называется манипулятором.
^

Таблица. Простые манипуляторы потока


Манипулятор

Действие

dec

Установка флага форматирования с десятичными преобразованиями.

hex

Установка флага форматирования с шестнадцатиричными преобразованиями.

oct

Установка флага форматирования с восьмиричными преобразованиями.

ws

Извлечение пробельных символов.

endl

Вставка символа новой строки и очистка потока.

ends

Вставка конечного пустого символа в строку.

flush

Сброс на диск и очистка ostream


Для работы с параметризованными манипуляторами надо дополнительно подключать файл iomanip.h .

Таблица. Параметризованные манипуляторы потока

setbase(int n)

Установка системы счисления при преобразованиях с основанием n (0, 8, 10 или 16). Нуль означает по умолчанию десятичную систему при выводе и правила С для литералов целых чисел при вводе.

resetiosflags(long f)

Очистка форматных бит в ins или outs, заданных аргументом f.

setiosflags(long f)

Установка бит форматирования в ins или outs, заданных аргументом f.

setfill(int c)

Установка символа-заполнителя в c.

setprecision(int n)

Установка точности представления чисел с плавающей точкой равной n разрядам

setw(int n)

Установка ширины поля в значение n


Манипуляторы воспринимают в качестве аргументов ссылку на поток и возвращают ссылку на тот же поток, поэтому манипуляторы могут объединяться в цепочку занесений в поток (или извлечений из потока) для того, чтобы изменять состояния потока в виде побочного эффекта, без фактического выполнения каких-либо занесений (или извлечений).







Скачать файл (357.8 kb.)

Поиск по сайту:  

© gendocs.ru
При копировании укажите ссылку.
обратиться к администрации
Рейтинг@Mail.ru