Tooprogram.ru

Компьютерный справочник
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Язык си ввод

Ввод-вывод в Си

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

Ввод и вывод информации осуществляется через функции стандартной библиотеки. Прототипы рассматриваемых функций находятся в файле stdio.h . Эта библиотека содержит функции

  • printf() — для вывода информации
  • scanf() — для ввода информации.

Вывод информации

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

Общая форма записи функции printf() :

СтрокаФорматов состоит из следующих элементов:

  • управляющих символов;
  • текста, представленного для непосредственного вывода;
  • форматов, предназначенных для вывода значений переменных различных типов.

Объекты могут отсутствовать.

Управляющие символы не выводятся на экран, а управляют расположением выводимых символов. Отличительной чертой управляющего символа является наличие обратного слэша ‘’ перед ним.

Основные управляющие символы:

  • ‘n’ — перевод строки;
  • ‘t’ — горизонтальная табуляция;
  • ‘v’ — вертикальная табуляция;
  • ‘b’ — возврат на символ;
  • ‘r’ — возврат на начало строки;
  • ‘a’ — звуковой сигнал.

Форматы нужны для того, чтобы указывать вид, в котором информация будет выведена на экран. Отличительной чертой формата является наличие символа процент ‘%’ перед ним:

  • %d — целое число типа int со знаком в десятичной системе счисления;
  • %u — целое число типа unsigned int ;
  • %x — целое число типа int со знаком в шестнадцатеричной системе счисления;
  • %o — целое число типа int со знаком в восьмеричной системе счисления;
  • %hd — целое число типа short со знаком в десятичной системе счисления;
  • %hu — целое число типа unsigned short ;
  • %hx — целое число типа short со знаком в шестнадцатеричной системе счисления;
  • %ld — целое число типа long int со знаком в десятичной системе счисления;
  • %lu — целое число типа unsigned long int ;
  • %lx — целое число типа long int со знаком в шестнадцатеричной системе счисления;
  • %f — вещественный формат (числа с плавающей точкой типа float );
  • %lf — вещественный формат двойной точности (числа с плавающей точкой типа double );
  • %e — вещественный формат в экспоненциальной форме (числа с плавающей точкой типа float в экспоненциальной форме);
  • %c — символьный формат;
  • %s — строковый формат.

Строка форматов содержит форматы для вывода значений. Каждый формат вывода начинается с символа % . После строки форматов через запятую указываются имена переменных, которые необходимо вывести.
Количество символов % в строке формата должно совпадать с количеством переменных для вывода. Тип каждого формата должен совпадать с типом переменной, которая будет выводиться на это место. Замещение форматов вывода значениями переменных происходит в порядке их следования.
Пример на Си

Результат работы программы

Тот же самый код может быть представлен с использованием одного вызова printf :

Табличный вывод

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

В приведенном примере 10 — общее количество знакомест, отводимое под значение переменной; 5 — количество позиций после разделителя целой и дробной части (после десятичной точки). В указанном примере количество знакомест в выводимом числе меньше 10, поэтому свободные знакоместа слева от числа заполняются пробелами. Такой способ форматирования часто используется для построения таблиц.

Ввод информации

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

Строка форматов аналогична функции printf() .
Для формирования адреса переменной используется символ амперсанд ‘&’ :
адрес = &объект

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

Результат работы программы:

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

Другой вариант — воспользоваться функцией защищенного ввода scanf_s( ) , которая появилась несколько позже, но содержит тот же самый список параметров.

Ввод данных в языке Си. Функция scanf

Пожалуйста, приостановите работу AdBlock на этом сайте.

Вернёмся к последнему листингу прошлого шага:

Основная задача этого шага научиться получить данные от пользователя.

Для этого можно использовать функцию scanf . Она, так же как и функция printf , описана в заголовочном файле stdio.h . Т.к. он у нас уже подключен в первой строке, то мы можем свободно использовать функцию scanf в своей программе.

Чтобы считать данные, которые ввёл пользователь, и сохранить их в переменную, нужно вызвать функцию scanf со следующими параметрами:

Рис.1. Общий синтаксис функции scanf.

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

Основные спецификаторы формата:

%d — целые числа
%f — вещественное число типа float
%lf — вещественное число типа double (обозначение lf от long float)
%c — символ

Читать еще:  Язык си уроки

Обратите внимание, что в функции scanf для типов float и double используются различные спецификаторы формата.

После формат-строки нужно указать адрес переменной, в которую нужно сохранить данные. Чтобы указать адрес переменной достаточно перед её именем записать знак & (амперсанд), как на рисунке выше.

Напишем, наконец-таки, программу сложения двух чисел.

Скомпилируйте и запустите эту программу. После того, как программа запущена она будет ждать пока вы введёте данные. Мы с вами знаем какие данные нужно вводить, т.к. мы писали эту программу. Для других пользователей, которые код программы не увидят, хорошо бы вывести на экран подсказку, какие данные нужно ввести. Посмотрите как это реализовано в следующем примере.

Эта программа будет полезна тем, кто следит за своим здоровьем. Данная программа подсчитывает уроверь базового обмена веществ по формуле Миффлина-Сан Жеора исходя из данных, которые вы введёте (возраст, рост и вес).

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

Практика

Решите предложенные задачи. Для удобства работы сразу переходите в полноэкранный режим

Исследовательские задачи для хакеров:

  1. Попробуйте удалить в программе Листинг 2 символ & в какой-нибудь функции scanf . Посмотрите какую ошибку выдаст компилятор.
  2. Попробуйте использовать %f для типа double , а %lf для типа float . Каковы результаты? Напишите об этом в комментариях к этому уроку. Не забудьте указать название вашей IDE или компилятора.

Язык си ввод

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

Основным понятием, связанным с информацией на внешних устройствах ЭВМ, является понятие файла. Всякая операция вво­да-вывода трактуется как операция обмена с файлами: ввод — это чтение из файла в оперативную память; вывод — запись инфор­мации из оперативной памяти в файл. Поэтому вопрос об органи­зации в языке программирования ввода-вывода сводится к вопро­су об организации работы с файлами.

Внутренний файл — это переменная файлового типа, являющаяся структурированной величиной. Элементы файловой переменной могут иметь разный тип и, со­ответственно, разную длину и форму внутреннего представле­ния. Внутренний файл связывается с внешним (физическим) файлом с помощью стандартной процедуры Assign. Один эле­мент файловой переменной становится отдельной записью во внешнем файле и может быть прочитан или записан с помощью одной команды. Попытка записать в файл или прочитать из него величину, не совпадающую по типу с типом элементов файла, приводит к ошибке.

Аналогом понятия внутреннего файла в языках Си/Си++ яв­ляется понятие потока. Поток — это байтовая последовательность, передаваемая в про­цессе ввода-вывода.

Поток должен быть связан с каким-либо внешним устройством или файлом на диске. В терминологии Си это звучит так; поток должен быть направлен на какое-то устройство или файл.

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

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

Существуют стандартные потоки и потоки, объявляемые в про­грамме. Последние обычно связываются с файлами на диске, со­здаваемыми программистом. Стандартные потоки назначаются и открываются системой автоматически. С началом работы любой программы открываются 5 стандартных потоков, из которых ос­новными являются следующие:

o stdin — поток стандартного ввода (обычно связан с клавиатурой);

o stdout — поток стандартного вывода (обычно связан с дисплеем);

o stderr — вывод сообщений об ошибках (связан с диспле­ем).

Кроме этого, открывается поток для стандартной печати и до­полнительный поток для последовательного порта.

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

Работа с файлами на диске. Работа с дисковым файлом начи­нается с объявления указателя на поток. Формат такого объяв­ления:

Слово file является стандартным именем структурного типа, объявленного в заголовочном файле stdio.h. В структуре file содержится информация, с помощью которой ведется работа с потоком, в частности: указатель на буфер, указатель (индикатор) текущей позиции в потоке и т.д.

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

Читать еще:  Умножение в ассемблере пример

Имя_указателя=fореn (“имя_файла”, “режим_открытия”) ;

Параметры функции fopen () являются строками, которые мо­гут быть как константами, так и указателями на символьные мас­сивы. Например:

Здесь test .dat — это имя физического файла в текущем ката­логе диска, с которым теперь будет связан поток с указателем fр. Параметр режима r означает, что файл открыт для чтения. Что касается терминологии, то допустимо употреблять как выражение «открытие потока», так и выражение «открытие файла».

Существуют следующие режимы открытия потока и соответ­ствующие им параметры:

r открыть для чтения

w создать для записи

а открыть для добавления

r+ открыть для чтения и записи

w+ создать для чтения и записи

а+ открыть для добавления или

создать для чтения и записи

Поток может быть открыт либо для текстового, либо для дво­ичного (бинарного) режима обмена.

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

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

Указанные выше параметры режимов открывают текстовые файлы. Если требуется указать на двоичный файл, то к параметру добавляется буква b. Например: rb, или « b », или r +b. В некоторых компиляторах текстовый режим обмена обозначается буквой t, т.е. записывается a+t или rt.

Если при открытии потока по какой-либо причине возникла ошибка, то функция fopen() возвращает значение константы null. Эта константа также определена в файле stdio.h. Ошибка может возникнуть из-за отсутствия открываемого файла на диске, нехватки места в динамической памяти и т.п. Поэтому желатель­но контролировать правильность прохождения процедуры откры­тия файла. Рекомендуется следующий способ открытия:

if (fp=fopen(«test.dat», «r»)==NULL)

В случае ошибки программа завершит выполнение с закрыти­ем всех ранее открытых файлов.

Закрытие потока (файла) осуществляет функция fclose(), прототип которой имеет вид:

int fclose(FILE *fptr);

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

Запись и чтение символов. Запись символов в поток произво­дится функцией putc() с прототипом

int putc (int ch, FILE *fptr);

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

Считывание символа из потока, открытого для чтения, произ­водится функцией gets () с прототипом

int gets (FILE *fptr);

Функция возвращает значение считываемого из файла сим­вола. Если достигнут конец файла, то возвращается значение EOF. Заметим, что это происходит лишь в результате чтения кода EOF.

Исторически сложилось так, что gets() возвращает значение типа int. To же можно сказать и про аргумент ch в описании функции puts(). Используется же в обоих случаях только млад­ший байт. Поэтому обмен при обращении может происходить и с переменными типа char.

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

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

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

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

Функция форматированного вывода printf получает в качестве аргументов строку формат и аргументы, которые необходимо вывести в соответствии с форматом, и возвращает число выведенных символов. В случае ошибки возвращает отрицательное значение и устанавливает значение ferror. Если произошло несколько ошибок, errno равно EILSEQ.
int printf (const char * format, . );

Функция проходит по строке и заменяет первое вхождение % на первый аргумент, второе вхождение % на второй аргумент и т.д. Далее мы будем просто рассматривать список флагов и примеры использования.

Общий синтаксис спецификатора формата
%[флаги][ширина][.точность][длина]спецификатор
Спецификатор – это самый важный компонент. Он определяет тип переменной и способ её вывода.

Таб. 1 Спецификатор типа.

СпецификаторЧто хотим вывестиПример
d или iЦелое со знаком в в десятичном виде392
uЦелое без знака в десятичном виде7235
oБеззнаковое в восьмеричном виде657
xБеззнаковое целое в шестнадцатеричном виде7fa
XБеззнаковое целое в шестнадцатеричном виде, верхний регистр7FA
f или FЧисло с плавающей точкой3.4563745
eЭкспоненциальная форма для числа с плавающей точкой3.1234e+3
EЭкспоненциальная форма для числа с плавающей точкой, верхний регистр3.1234E+3
gКратчайшее из представлений форматов f и e3.12
GКратчайшее из представлений форматов F и E3.12
aШестнадцатеричное представление числа с плавающей точкой-0xc.90fep-2
AШестнадцатеричное представление числа с плавающей точкой, верхний регистр-0xc.90FEP-2
cБукваa
sСтрока (нуль-терминированный массив букв)Hello World
pАдрес указателяb8000000
nНичего не пачатает. Аргументом должен быть указатель на signed int. По этому адресу будет сохранено количество букв, которое было выведено до встречи %n
%Два идущих друг за другом процента выводят знак процента%

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

Таб. 2 Флаги.

ФлагОписание
Выключка влево на заданное шириной значение
+Явно указывать знак у числа, даже для положительных чисел
(пробел)Если знак не будет выведен, то вставляет пробел перед выводимым числом
#Когда используется вместе с o, x или X, вставляет перед числом 0, 0x или 0X
Когда используется со спецификаторами a, A, e, E, f, F, g или G, вставляет десятичную точку, даже если после неё нет десятичных знаков.
Вставляет нули, когда объявлен спецификатор ширины
Таб. 3 Ширина.

ШиринаОписание
(число)Минимальное количество знаков, которое необходимо вывести. Если в числе меньше знаков, то вставляет пробелы (или нули)
*Ширина не указана в строке формата, она передаётся отдельно в виде аргумента, который должен предшествовать выводимому числу
Таб. 4 Точность.

.ТочностьОписание
.числоДля спецификаторов целых (d, i, o, u, x, X) точность определяет минимальное количество знаков, которое необходимо вывести. Если значение короче, то выводятся нули перед числом. Значение не обрезается, даже если оно длиннее. Точночть 0 означает, что для значения 0 ничего не выводится.
Для спецификаторов чисел с плавающей точкой (a, A, e, E, f, F) это число знаков, которые необходимо вывести после десятичной точки (по умолчанию 6).
Для g и G — это число значащих разрядов, которые необходимо вывести.
Для s — выводится указанное число символов. По умолчанию выводятся все символы до первого нулевого.
Если число не стоит, то по умолчанию точность равна 0
.*Точность не указана в строке формата, она передаётся отдельно в виде аргумента, который должен предшествовать выводимому числу

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

Таб. 5 Длина.

спецификаторы
Длинаd, iu o x Xf F e E g G a Acspn
(none)intunsigned intdoubleintchar*void*int*
hhsigned charunsigned charsigned char*
hshort intunsigned short intshort int*
llong intunsigned long intwint_twchar_t*long int*
lllong long intunsigned long long intlong long int*
jintmax_tuintmax_tintmax_t*
zsize_tsize_tsize_t*
tptrdiff_tptrdiff_tptrdiff_t*
Llong double

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

Рассмотрим форматированный ввод функцией scanf.
int scanf(const char*, . )
Функция принимает строку формата ввода (она похожа на строку формата printf) и адреса, по которым необходимо записать считанные данные. Возвращает количество успешно проинициализированных аргументов.
Формат спецификатора ввода
%[*][ширина][длинна]спецификатор

Таб. 6 Спецификатор типа.

СпецификаторОписаниеВыбранные символы
i, uЦелыеПроизвольное число цифр (0-9), возможно, начинающихся с + или -. Если число начинается с 0, то считывается в восьмеричном формате, если с 0x, то в шестнадцатеричном.
dДесятичное целоеПроизвольное число цифр (0-9), возможно, начинающихся с + или -.
oвосьмеричное целоеПроизвольное число цифр (0-7), возможно, начинающихся с + или -.
xШестнадцатеричное целоеПроизвольное число цифр (0-F), возможно, начинающихся с + или — и префикса 0x или 0X.
f, e, gЧисло с плавающей точкойЧисло, состоящее из набора цифр 0-9, возможно с десятичным разделителем (точкой). Возможно также представление в экспоненциальной форме. C99 позволяет также вводить число в шестнадцатеричном формате.
a
cСимволЕсли ширина не передана, то считывает один символ. Если ширина передана, то считывает нужное количество символов и размещает их в массиве БЕЗ терминального символа на конце.
sСтрокаСчитывает все не пробельные символы. Если указана ширина, то не более n символов. Ставит на место n+1 символа терминальный.
pАдрес указателяПоследовательность символов, трактуемая как адрес указателя. Формат зависит от реализации, но совпадает с тем, как выводит printf с ключом p
[символы]Множество символовСчитывает только те символы, которые записаны в квадратных скобках, С99
[^символы]Множество символовСчитывает только те символы, которые не указаны в квадратных скобках, С99
nНичего не считываетСохраняет число уже считанных символов по указанному адресу

Как и в printf, ширина, заданная символом * ожидает аргумента, который будт задавать ширину. Флаг длина совпадает с таким флагом функции printf.

Кроме функций scanf и printf есть ещё ряд функций, которые позволяют получать вводимые данные

int getch() [aka _getch(), getchar()] — возвращает введённый символ, при этом не выводит его на консоль.

char * fgets ( char * str, int num, FILE * stream ) — функция позволяет считывать строку с пробельными символами. Несмотря на то, что она работает с файлом, можно с её помощью считывать и из стандартного потока ввода. Её преимущество относительно gets в том, что она позволяет указать максимальный размер считываемой строки и заканчивает строку терминальным символом.

Это не полный набор различных функций символьного ввода и вывода. Таких функций море, но очень многие из них небезопасны, поэтому перед использованием внимательно читайте документацию.

Непечатные символы

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

Ссылка на основную публикацию
Adblock
detector