Главная страница

Курс на Си. Подбельский. Курс программирования на Си. В., Фомин С. С. Курс программирования на языке Си Учебник


Скачать 1.57 Mb.
НазваниеВ., Фомин С. С. Курс программирования на языке Си Учебник
АнкорКурс на Си
Дата18.02.2023
Размер1.57 Mb.
Формат файлаdocx
Имя файлаПодбельский. Курс программирования на Си.docx
ТипУчебник
#943863
страница23 из 42
1   ...   19   20   21   22   23   24   25   26   ...   42

Ввод-вывод строк. Одной из наиболее популярных операций ввода-вывода является операция ввода-вывода строки символов. В библиотеку языка Си для обмена со стандартными потоками вво­да-вывода включены функции ввода-вывода строк gets( ) и puts( ). Прототипы этих функций имеют следующий вид:

char * gets(char * s); /* Функция ввода */

int puts(char * s); /* Функция вывода */

Обе функции имеют только один аргумент - указатель s на мас­сив символов. Если строка прочитана удачно, функция gets( ) воз­вращает адрес того массива s, в который производился ввод строки. Если произошла ошибка, то возвращается NULL.

Функция puts( ) выводит в стандартный выходной поток сим­волы из массива, адресованного аргументом. В случае успешного завершения возвращает последний выведенный символ, который всегда является символом '\n'. Если произошла ошибка, то возвра­щается EOF.

Приведем простейший пример использования этих функций.

#include

char str1[ ] = "Введите фамилию сотрудника:";

int main() {

char name[80];

puts(str1);

gets(name); return 0;

}

Напомним, что любая строка символов в языке Си должна за­канчиваться терминальным символом '\0'. В последний элемент массива str1 терминальный символ будет записан автоматически при инициализации массива. Для функции puts( ) наличие нуль- символа в конце строки является обязательным. В противном слу­чае, то есть при отсутствии в символьном массиве символа '\0', программа может завершиться аварийно, так как функция puts( ) в поисках нуль-символа будет перебирать всю доступную память байт за байтом, начиная в нашем примере с адреса str1. Об этом необходимо помнить, если в программе происходит формирование строки для вывода ее на экран дисплея. Функция gets( ) завершает свою работу при вводе символа '\n', который автоматически пере­дается от клавиатуры в ЭВМ при нажатии на клавишу . При этом сам символ '\n' во вводимую строку не записывается. Вместо него в строку помещается терминальный символ '\0'. Таким обра­зом, функция gets( ) производит ввод «правильной» строки, а не просто последовательности символов.

Здесь следует обратить внимание на следующую особенность вво­да данных с клавиатуры. Функция gets( ) начинает обработку ин­формации от клавиатуры только после нажатия клавиши . Таким образом, она «ожидает», пока не будет набрана нужная ин­формация и нажата клавиша . Только после этого начина­ется ввод данных в программу.

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

Для работы со стандартными потоками в режиме форматного вво­да-вывода определены две функции:

  • printf( ) - форматный вывод;

  • scanf( ) - форматный ввод.

Форматный вывод в стандартный выходной поток. Прототип функции printf( ) имеет вид:

int printf(const char *format, . . .);

При обращении к функции printf( ) возможны две формы зада­ния первого параметра:

int printf ( форматная_строка, список_аргументов);

int printf ( указатель_на_форматную_строку, список_аргументов);

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

Возвращаемое значение функции printf( ) - число напечатанных символов; а в случае ошибки - отрицательное число.

Форматная_строка ограничена двойными кавычками и может включать произвольный текст, управляющие символы и специфи­кации преобразования данных. Текст и управляющие символы из форматной строки просто копируются в выходной поток. Формат­ная строка обычно размещается в списке аргументов функции, что соответствует первому варианту вызова функции printf( ). Второй вариант предполагает, что первый аргумент - это указатель типа char *, а сама форматная строка определена в программе как обыч­ная строковая константа или переменная.

В список аргументов функции printf( ) включают выражения, значения которых должны быть выведены из программы. Частные случаи этих выражений - переменные и константы. Количество аргументов и их типы должны соответствовать последовательности спецификаций преобразования в форматной строке. Для каждого аргумента должна быть указана точно одна спецификация преобра­зования.

Если аргументов недостаточно для данной форматной строки, то результат зависит от реализации (от операционной системы и от системы программирования). Если аргументов больше, чем указано в форматной строке, «лишние» аргументы игнорируются.

Список_аргументов (с предшествующей запятой) может отсут­ствовать.

Спецификация преобразования имеет следующую форму:

% флаги ширина_поля.точность модификатор спецификатор

Символ % является признаком спецификации преобразования. В спецификации преобразования обязательными являются только два элемента: признак % и спецификатор.

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

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

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

Таблица 7.1. Спецификаторы форматной строки для функции форматного вывода

Специ­фикатор

Тип аргу­мента

Формат вывода

d

int, char, unsigned

Десятичное целое со знаком

i

int, char, unsigned

Десятичное целое со знаком

u

int, char, unsigned

Десятичное целое без знака

o

int, char, unsigned

Восьмеричное целое без знака

x

int, char, unsigned

Шестнадцатеричное целое без знака; при выводе ис­пользуются символы «0...9a...f»

X

int, char, unsigned

Шестнадцатеричное целое без знака; при выводе ис­пользуются символы «0...9A...F

f

double, float

Вещественное значение со знаком в виде: знак_числа dddd.dddd, где dddd - одна или более десятичных цифр. Количество цифр перед десятичной точкой зависит от величины вы­водимого числа, а количество цифр после десятичной точки зависит от требуемой точности. Знак_числа при отсутствии модификатора '+' изображается только для отрицательного числа


Таблица 7.1. Спецификаторы форматной строки для функции форматного вывода (окончание)

Специ­фикатор

Тип аргу­мента

Формат вывода

e

double, float

Вещественное значение в виде:

знак_числа m.dddde знакххх,

где m.dddd - изображение мантиссы числа; m - одна де­сятичная цифра; dddd - последовательность десятичных цифр; e - признак порядка; знак - знак порядка; xxx - десятичные цифры для представления порядка числа; знак_числа при отсутствии модификатора '+' изобража­ется только для отрицательного числа

E

double, float

Идентичен спецификатору «е», за исключением того, что признаком порядка служит «Е»

g

double, float

Вещественное значение со знаком печатается в формате спецификаторов «f» или «е» в зависимости от того, какой из них более компактен для данного значения и точности. Формат спецификатора «е» используется тогда, когда значение показателя меньше -4 или больше заданной точности. Конечные нули отбрасываются, а десятичная точка появляется, если за ней следует хотя бы одна цифра

G

double, float

Идентичен формату спецификатора «g», за исключением того, что признаком порядка служит «Е»

c

int, char, unsigned

Одиночный символ

s

char *

Символьная строка. Символы печатаются либо до перво­го терминального символа ('\0'), или печатается то коли­чество символов, которое задано в поле точность спе­цификации преобразования

p

void *

Значение адреса. Печатает адрес, указанный аргумен­том (представление адреса зависит от реализации)

Приведем примеры использования различных спецификаторов. В каждой строке с вызовом функции printf( ) в качестве коммен­тариев приведены результаты вывода. Переменная code содержит код возврата функции printf( ) - число напечатанных символов при выводе значения переменной f.

#include int main()

{

int number = 27;

float f = 123.456;

char str[4] =

"abc";










char c = 'a'

;










int code;













printf("%d\n",

number);

/*

27

*/

printf("%o\n",

number);

/*

33

*/

printf("%x\n",

number);

/*

1b

*/

code = printf(

"%f\n", f);

/*

123.456001

*/

printf("code =

%d\n", code);

/*

code = 11

*/

printf("%e\n",

f);

/*

1.23456e+02

*/

printf("%c\n",

c);

/*

a

*/

printf("%s\n",

str);

/*

abc

*/

return 0;

}

Необязательные элементы спецификации преобразования управ­ляют другими параметрами форматирования.

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

  • «-» - выводимое изображение значения прижимается к ле­вому краю поля. По умолчанию, то есть при отсутствии этого флага, происходит выравнивание по правой границе поля;

  • + - используется для обязательного вывода знака числа. Без этого флага знак выводится только при отрицательном зна­чении;

  • пробел - используется для вставки пробела на месте знака перед положительными числами;

  • # - если этот флаг используется с форматами «o», «х» или «Х», то любое ненулевое значение выводится с предшествую­щим 0, 0х или 0Х соответственно. При использовании флага # с форматами «f», «g», «G» десятичная точка будет выводиться, даже если в числе нет дробной части.

Примеры использования флагов:

  • «%+d» - вывод знака '+' перед положительным целым деся­тичным числом;

  • «% d» - добавление (вставка) пробела на месте знака перед положительным числом (использован флаг пробел после сим­вола %);

  • «%#о» - печать ведущих нулей в изображениях восьмеричных чисел.

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

Если число символов в изображении выводимого значения боль­ше, чем определено в ширине_поля, или ширина_поля не задана, пе­чатаются все символы выводимого значения.

Точность указывается с помощью точки и необязательной после­довательности десятичных цифр (отсутствие цифр эквивалентно 0).

Точность задает:

  • минимальное число цифр, которые могут быть выведены при использовании спецификаторов d, i, o, u, x или X;

  • число цифр, которые будут выведены после десятичной точки при спецификаторах e, E и f;

  • максимальное число значащих цифр при спецификаторах g и G;

  • максимальное число символов, которые будут выведены при спецификаторе s.

Непосредственно за точностью может быть указан модификатор, который определяет тип ожидаемого аргумента и задается следую­щими символами:


написать администратору сайта