Лекции.Орг


Поиск:




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




Возвращает функция количество выведенных символов или отрицательное значение, в случае ошибки. Для ввода-вывода в стиле С необходимо подключать заголовочный файл <stdio.h>. Вывод осуществляется в стандартный поток вывода stdout.

 

В "управляющей строке"  могут быть:

  • обычные символы (текст),
  • управляющие символьные константы (\n – новая строка, \t – табуляция, \a – звуковой сигнал,  …),
  • спецификации преобразования – последовательность символов, начинающаяся с символа %.

Формат спецификации преобразования в "управляющей строке" включает: обязательный символ%’ (1 –я колонка таблицы),   необязательные символы (флаги, ширина поля вывода, точность, модификатор вывода) (2 –я колонка таблицы) и обязательныйсимвол тип преобразования (3-я колонка таблицы).

 

Таблица 7. Формат спецификации преобразования в управляющей строке для функции printf()

обязательный символ необязательный символ флаги   обязательный символ тип преобразования  
% +          – для вывода знака перед значением; ‘ ‘     – для вывода пробела вместо знака для положительного числа; -      – для выравнивания влево выводимого числа; #           – для вывода символа системы счисления  (0 – для 8-ричной, 0х или 0Х – для 16-ричной); ширина поля вывода (воздействует только на вывод): min       – для задания минимальной ширины поля вывода в min символов (строка цифр); 0 min – то же самое, но позиции слева для целого числа дополняются нулями; точность (воздействует только на вывод): .0         – для d, i, o, u, x – точность по умолчанию; – для e, E, f –  отсутствие десятичной точки; . precision – максимальное число символов, которое надо вывести, или же число цифр после точки в типах float или double; модификатор вывода h           – для d, i, o, u, x аргумент имеет тип short; l       – для d, i, o, u, x аргумент имеет тип long, для e, f, g аргумент является double   отсутствие «флага» – означает значение «по умолчанию» для спецификации вывода; c      – для вывода символа d, i – для 10-ичного представления целого знакового значения   (signed int) o      – для 8-ичного представления целого беззнакового значения (unsigned int) u      – для 10-ичного представления целого беззнакового значения  (unsigned int) x  – для 16-ичного представления целого беззнакового значения (unsigned int) f        – для представления вещественных значений  в форме ±mmmm.nnnnnn (float) e, Е   – для представления вещественных значений   в форме ±m.nnnnnnE±xx (float) g, G – для представления вещественных значений в форме e или f (в зависимости от значения и специфицированной точности) s      – для представления строк p – для представления указателя (адреса)  

 

Ширина поля вывода – это минимальное количество позиций, отводимых под число. Если указанного количества позиций для размещения значения недостаточно, автоматически выделяется требуемое количество позиций. Поэтому для «красивого» вывода необходимо определять значение ширины поля с учетом: точности, формы представления вещественного числа и отводимых для этого позиций, знака числа, предполагаемого количества цифр в его целой части, обязательного перед числом пробела (значение ширины поля должно (как минимум) превышать значение задаваемого модификатора точности).

Смысл модификатора точности precision, задаваемого десятичным числом, зависит от спецификации формата, с которой он используется:

· при выводе строки (например, спецификация %Ns) precision N указывает число символов N для вывода строки;

· при выводе вещественного числа (например, спецификация %Nf  или %Ne) precision N  указывает количество цифр N, выводимых после десятичной точки;

· при выводе вещественного числа (например, спецификация %Nd  или %Ni) precision N указывает минимальное количество N выводимых цифр; если число представляется меньшим количеством цифр, чем указано в precision, выводятся ведущие (начальные) нули;

· при выводе вещественного числа (например, спецификация %Ng или %NG) precision N  указывает максимальное количество значащих цифр, которые будут выводиться.

 

Флаг ‘-‘ указывает на то, что значение выравнивается по левому краю и, если нужно, дополняется пробелами справа. При отсутствии минуса значение выравнивается по правому краю и дополняется пробелами слева.

Модификаторы h и l перед спецификацией (например, %lf, %hu) означают:

· h  с типами d, i, o, x и Х указывает на то, что тип аргумента short int,  а с типом u – short unsigned int;

· l  с типами d, i, o, x и Х указывает на то, что тип аргумента longt int,   с типом u – long unsigned int, с типами e, E, f, g, G – double, а не float.

 

Содержание спецификаций преобразования выглядит так:

% выводится символ %;
d, i аргумент преобразуется к десятичному целому;
e, E аргумент рассматривается как переменная типа float  или double, преобразуется в десятичную форму в виде [-]m.nnnnnn[+-]xx, где длина строки из n определяется указанной точностью; точность по умолчанию равна 6;
f аргумент, рассматриваемый как переменная типа float  или double, преобразуется в десятичную форму в виде [-]mmm.nnnn, где длина строки из n  определяется указанной точностью; точность по умолчанию равна 6;
g, G используется формат %e или %f, который короче; незначащие нули не печатаются
о аргумент преобразуется в форму беззнакового восьмеричного (без лидирующего нуля);
р вывод указателя в шестнадцатеричном формате (спецификация не входит в стандарт, но существует практически во всех реализациях);
s аргумент является строкой: символы строки печатаются до тех пор, пока не будет достигнут нулевой символ или не будет напечатано количество символов, указанное в спецификации точности;
u аргумент преобразуется в форму беззнакового десятичного;
х, Х аргумент преобразуется в форму беззнакового шестнадцатеричного (без лидирующих 0х).
   

 

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

С помощью операторов вывода нельзя вывести:

¨ значение переменной типа «перечисление»;

¨ значение переменной типа «массив» (необходимо выводить значения отдельных его элементов);

¨ значение переменной типа «структура» (необходимо выводить значения отдельных полей).

-----------------------------------------------------------------------------------------

Ввод строк в С выполняет функция int gets(char * str).  Функция читает символы из стандартного потока ввода stdin в массив по указателю str, в котором сохраняется строка до тех пор, пока не будет обнаружен символ новой строки ’\n’ или признак конца файла. Символ ’\n’ отбрасывается, и строка завершается ограничителем ’\0’. При обнаружении конца файла или ошибки возвращается NULL.

char str[20];

gets(str); //qwer  qwert  qwerty

puts(str); //qwer qwert qwerty

 

Функция gets() не позволяет установить ограничение на количество считываемых символов, поэтому нужно быть осторожными с размером массива, на который указывает параметр str, чтобы избежать переполнения буфера.

Форматный ввод из стандартного потока ввода stdin ("привязан" к клавиатуре) в переменные программы обеспечивает функцияscanf(), в соответствии с «управляющей строкой». При вводе, очевидно, выполняется преобразование из внешнего символьного вида во внутренний двоичный формат. Функция возвращает количество успешно введенных значений. В случае ошибки функция возвращает системную константу EOF (обычно эта константа определена как –1).

Функция scanf(), в отличие от gets(), выполняет ввод строки с пробелами не полностью, а лишь до первого пробела.

Формат оператора ввода:

int scanf("управляющая строка", арг1, арг2, ….);

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

При выполнении оператора форматного ввода программа приостанавливает свою работу и ждет, пока на клавиатуре будут набраны значения и нажата клавиша <Enter>. После нажатия <Enter>, введенное значение присваивается переменной, имя которой указано в списке аргументов (является следующим по порядку). Первое набранное на клавиатуре значение становится значением первой переменной в списке ввода.

Формат ввода значений переменных задается при помощи спецификатора преобразования – последовательности символов, начинающейся с символа % (см. Таблицу 2).

 

Таблица 8. Формат спецификации преобразования в управляющей строке для функции scanf()

обязательный символ необязательный символ флаги обязательный символ тип преобразования
% число – максимальный размер поля ввода l – тип long для d, o, x, u или double для f, e h –тип short для d, o, x, u d – 10-ичное представление o – 8-ичное представление x – 16-ичное представление c – символ s – строка l – float или double f – float или double u – беззнаковое целое p – указатель (адрес)

 

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

 

Правило:

1. функция scanf() вводит только до пустого символа (пробел, ’\t’, ’\n’, ’\v’);

2. при вводе строки функция scanf() считывает столько символов, сколько указано в объявлении строковой переменной; пробел при этом считается разделителем, ввод строки проводится только до пробела;

3. в списке аргументов перед именем переменной надо ставить &;  при вводе значения строковой переменной символ & ставить не надо.

4. в качестве разделителя значений (при вводе нескольких переменных одной последовательностью), как правило,  используются пробельные символы.

Например:

short sh; int ii; unsigned uu; long ll;

scanf("%hd %d %u %li", & sh, & ii, & uu, & ll); // вводим: 1 2 3 4<enter>

                              // или: 1<enter>2<enter>3<enter>4<enter>

Элементы вводимых данных должны разделяться пробелами, знаками табуляции или новой строки.
Знаки пунктуации, такие как запятая, точка с запятой и т.п., не считаются разделителями. Это значит, что для оператора scanf("%d%d", &r, &с); последовательность 10 20 будет воспринята, а последовательность 10,20 – нет.

 

scanf("%hd,%d,%u,%li", & sh, & ii, & uu, & ll); // вводим: 1,2,3,4<enter>

Наличие обычного символа (например,) в управляющей строке заставляет scanf() считать и отбросить этот символ. Например, "%d,%d" заставляет scanf() считать целое число, считать и отбросить запятую и затем считать еще одно целое число. Если указанный символ не обнаружен во входном потоке, scanf() останавливается.

Строки считываются в массивы символов, а имя массива, без всякого указателя, является адре­сом первого элемента массива. Поэтому, чтобы считать строку в массив символов addr, можно использовать команду scanf("%s", addr); (в этом случае имя addr уже является указателем и не нуждается в префиксе &).

 

!!! Использование в качестве параметра функции scanf() имени переменной, а не ее адреса, является типичной ошибкой (компилятор эту ошибку не обнаруживает).

 

С помощью операторов ввода нельзя ввести:

¨ значение логической переменной;

¨ значение переменной типа «перечисление»;

¨ значение переменной типа «массив» (необходимо вводить значения отдельных элементов);

¨ значение переменной типа «структура» (необходимо вводить значения отдельных полей).

 

Логическое значение можно получить с помощью ввода значений переменной целочисленного типа и последующего приведения типов. Аналогично, c помощью ввода значений переменной беззнакового целочисленного типа и последующего приведения типов, можно проинициализировать переменную перечислимого типа.

-----------------------------------------------------------------------------------------

Ввод/вывод в стиле С++

В отличие от процедурно-ориентированной библиотеки <stdio.h>, в С++ реализована новая библиотека ввода-вывода – объектно-ориентированная, получившая название <iostream>. В ней концепция «поточного» ввода-вывода получила свое дальнейшее развитие. Главным достоинством системы ввода-вывода С++ является то, что она может перегружаться для создаваемых новых классов, что позволяет легко встраивать в систему ввода-вывода С++ новые создаваемые типы данных.

Система ввода-вывода С++ состоит из двух уровней:

· Физический уровень – либо внешний файл (т.е. именованная область внешней памяти, содержащая какую-либо информацию),либо область памяти,либо логическое устройство компьютера, имеющее свое фиксированное имя.

· Логический уровень – это «логическое устройство» – поток – структура данных, используемая при программировании, существующая в логическом представлении программиста при написании программы (представляется в программе потоковой переменной определенного типа). После того как в программе создан поток, он может быть использован как средство общения с любым физическим файлом или устройством.

 

Средства ввода-вывода обеспечивают программиста механизмом для извлечения данных из потоков и для включения данных в потоки:

o операция «извлечение из потока» – >> ( перегруженнаяоперация сдвига вправо)– заключается в преобразовании последовательности символов потока во внутреннее представление в памяти  значения типизированного объекта; внешнее представление данных – символьное; внутреннее представление данных – последовательность двоичных кодов, регламентированная для каждого типа данных;

o операция «включение в поток» – << ( перегруженная операция сдвига влево)– предполагает обратное преобразование – внутреннего представления в памяти  типизированного значения (int, float, char, …..) в последовательность символов потока; при выводе на экран идет преобразование двоичных кодов в символы алфавита, изображаемые на внешнем устройстве.

При включении в программу заголовка <iostream> в программе автоматически становятся доступными стандартные потоки (глобальные потоковые объекты):

cin – объект класса istream, соответствующий стандартному потоку ввода, по умолчанию связан с клавиатурой;

cout – объект класса ostream, соответствующий стандартному потоку вывода, по умолчанию связан с экраном.

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

 

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

При этом при вводе:

o вся вводимая информация (как строка текста) помещается в буфер ввода;

o ввод завершается нажатием клавиши <enter>; а извлечение из буфера происходит  только после нажатия <enter>;

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

o чтение начинается с первого непробельного символа,начальные пробельные символы игнорируются;

o ограничителем значения числа является нечисловой или пробельный символ; ограничителем строки – пробельный символ;

o ввод в переменную прекращается при наборе недопустимого для её типа символа (например, для операторов int ii; double dd; cin >> ii; cin >> dd;   при наборе на клавиатуре значения 123. 456,  ii получит значение 123, а dd – значение 0. 456);

o при вводе целых чисел читаются: +, -, десятичная цифра; числа должны во входном потоке разделяться обобщенными пробельными символами (пробел, знак табуляции, перевод строки, <enter>);

o при вводе 16-ичных целых чисел дополнительно читаются также буквы a, A, b, B, ….f, F;

o при вводе вещественных чисел – дополнительно читаются символы e или E и «точка»;

o булевские значения вводятся как 1 (true) и 0 (false);

o ввод перечислимого типа как целого по умолчанию не работает; для каждого нового перечислимого типа необходимо писать собственные операции ввода-вывода;

o ввод символа (даже единственного) заканчивается нажатием клавиши <enter>; при вводе символов игнорируются пробельные символы, поэтому последовательность символов «qwe» можно задать разными способами (перемежая пробелами или нажатием <enter>); манипулятор noskipws позволяет не пропускать пробелы (cin >> noskipws  >> c1 >> c2 >> c3;); ввод символа реализуется также операторами: ch = cin. get (); cin. get (ch); cin. read (& ch,1); ввести целое значение в символьную переменную нельзя (даже при наборе цифры, в символьную переменную попадает код); однако символьные типы могут использоваться в арифметических выражениях, 

o при вводе строки в символьный массив, в буфер входного потока заносится вся введенная информация с завершающими символами (\r\n), формируемыми при нажатии клавиши <enter>; при каждой операции «извлечение» – извлечение символов происходит только до ближайшего пробела; в строку заносится завершающий символ ‘\0’;

o для ввода строк с пробелами в символьный массив используются методы cin. get (), cin. getline (); метод cin. ignore() извлекает символы из потока, ничего не занося в переменные и имеет два параметра (количество удаляемых символов, по умолчанию – 1, символ-ограничитель, который тоже удаляется из потока, по умолчанию – конец файла);

при выводе:

o целые числа выводятся в десятичной системе счисления; шестнадцатеричная константа 0xFFFF на экране будет показана как десятичное число 65535;

o для вещественного числа выводится 6 цифр после запятой (например, число 7.123456789 выводится как 7 .123457, а число 123456789.15 – как 123456789.150000 или 1.234568е+008;

o указатели по умолчанию выводятся в шестнадцатеричной системе счисления, независимо от типа; исключение составляет указатель на символьную константу: по умолчанию выводится не указатель, а строка символов, на которую он указывает, поэтому для вывода указателя необходимо преобразование типа к типу void* (char* s = ”aaaaa\n”; cout << s << “ “  << static_cast<void*>(s) << ‘\n’;);

o значения типа bool выводятся как целые (1 – true, 0 – false);

o значения перечислимого типа по умолчанию выводятся как целые;

o символьные переменные по умолчанию выводятся как символы; чтобы вывести символьную переменную как число, необходимо задать явное преобразование типа (char n = -100; cout << int(n) << ‘\n’; одиночный символ можно вывести методом put () (char ch = ‘a’; cout.put(ch);) или методом write() (char ch =’a’; cout.write(&ch, 1);

o при выводе строки из памяти в выходной поток переносятся все символы до ‘\0’; Операция оператор << работает и с символьными массивами и со строками типа string (string s3 = “aaaaa\n”; cout << s3;); вывести строку (кроме переменных типа string) можно и методом write() (char *s1=”bbbbb”; cout. write(s1, strlen(s1));

o при выводе выражений необходимо учитывать приоритет операций; оператор << изначально является операцией сдвига влево и имеет свой приоритет (например, cout << d = f << ‘\n’; интерпретируется как (cout << d) = (f << ‘\n’); и вызовет ошибку трансляции; исправление: cout << (d = f) << ‘\n’;)

-----------------------------------------------------------------------------------------





Поделиться с друзьями:


Дата добавления: 2018-10-15; Мы поможем в написании ваших работ!; просмотров: 247 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

В моем словаре нет слова «невозможно». © Наполеон Бонапарт
==> читать все изречения...

780 - | 734 -


© 2015-2024 lektsii.org - Контакты - Последнее добавление

Ген: 0.009 с.