Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Си_3.doc
Скачиваний:
3
Добавлен:
25.08.2019
Размер:
192 Кб
Скачать

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

Строка описания форматов ввода может содержать:

  1. спецификации формата, которые определяются символом % - для выделения, контроля и преобразования соответствующих им введённых значений;

  2. любые символы, которые могут быть во входном потоке и которые надо игнорировать;

  3. пробельные символы: пробел, символ табуляции (‘\t’), символ новой строки (‘\n’) и возврата каретки (‘\r’).

Если в строке появился пробел, то с этого момента ввод завершается, из входного потока считываются и игнорируются пробелы до первого не пробела.

Если в строке format встретились непробельные символы, например, последовательность латинских букв и цифр, за исключением ‘%’, то из входного потока такие же символы считываются и игнорируются.

Появление в строке format ‘%’ определяет начало формата для очередного аргумента. Формат предписывает функции типа scanf прочитать и преобразовать очередные символы входного потока в значение типа, определённого форматом. Значение выделяется из входного потока, преобразуется в соответствии с форматом, контролируется на соответствие типу переменной и присваивается переменной аргумента, адрес которой указан в соответствующем формату элементе списка аргументов. Если выделенное значение не соответствует типу формата, результат ввода неопределён. Это может произойти, например, при вводе форматом “%d” значения для переменной типа float или буквы. Сообщение при этом не выдаётся и продолжается выполнение программы.

При несоответствии типов форматов типам аргументов вводимых значений программа завершается аварийно на этапе её выполнения. Во время трансляции эта ошибка не обнаруживается. Это может быть, например, при попытке форматом “%f” ввести значение для переменной целого или строчного типа.

При этом выдаётся сообщение:

scanf: floating point format not linked

Abnormal program termination, или

scanf: формат для плавающей точки недопустим

Аварийное завершение программы.

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

  1. первого пробельного символа (кроме ввода по формату “%c”);

  2. первого символа, который не соответствует формату (например, буква или пробел после выделения числа);

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

Формат (спецификация формата) не содержит пробелов и может быть записана:

%[*][w] [F | N|h|l|L]тип

где % - признак начала формата;

* - запрет присваивания аргументу (переменной) введённого значения;

w – width – ширина-десятичное целое, определяет максимальный размер поля вводимого значения;

F|N – определяет тип адресации аргумента (far, near);

h|l|L – определяет уточнение типа аргумента вводимого значения, то есть вариант типа: l или L –long или double, h - short;

тип – это символ типа формата вводимого значения.

В квадратных скобках указаны необязательные элементы формата.

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

Спецификаторам d, i, o, u, x может предшествовать:

h – если аргументы – указатели на тип short int;

l – если аргументы – указатели на тип long int;

Спецификаторам e, E, f, F может предшествовать:

l – если аргументы – указатели на тип double (а не float);

L – если аргументы – указатели на тип long double.

Примеры типов форматов ввода представлены в таблице.

Тип формата

Интерпретация значения, выделенного при вводе

Тип аргумента – указатель на

d

десятичное целое

int

D

десятичное целое

long

o

восьмеричное целое

int

O

восьмеричное целое

long

x

шестнадцатеричное целое

int

X

шестнадцатеричное целое

long

i

десятичное, восьмеричное или шестнадцатеричное целое

Int

u

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

unsigned int

U

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

unsigned long

e, E

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

float/ double

f, F

число с фиксированной точкой

float/ double

c

символ, в том числе пробел

char

s

строка

char

n

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

int

Значение с плавающей точкой, вводимое по форматам f, F, e, E во входном потоке, может содержать число с фиксированной точкой и (необязательно) экспоненту – символ e или E, за которым следует порядок.

Пример

123 1.23 1.23e-2 1.23E-2

С помощью формата с вводится очередной символ, в том числе пробельный. Чтобы ввести строку из N символов, включая и пробелы, и символ конца строки ‘\n’, надо использовать формат “%wc”. Если при вводе строки форматом “%wc” введён символ перехода на следующую строку, то при выводе этой строки он вызовет переход на следующую строку, на которой и будет продолжен вывод.

С помощью формата s вводится строка символов до очередного пробела. После последнего символа введённой строки помещается символ ‘\0’ – конца строки. Символы перехода на следующую строку ‘\n’ считываются наравне с другими символами. Для чтения следующего непробельного символа можно воспользоваться форматом “\1s”.

С помощью формата “ %ws”можно пропустить очередное поле с w-непробельными символами. С помощью формата “ %*10c”будут пропущены очередные 10 любых символов, в том числе пробельных символов входного потока. Для таких форматов аргументы не требуются.

Пример

scanf(“%d%ld%f%c%12c%s%*c”, &i, &k, &a, &b, str,str2);

Для формата “%n” из входного потока не производится чтение очередного значения для очередного аргумента, но значение в ОП, соответствующее очередному аргументу, может быть искажено.

Если в строке форматов стоит символ, который не является символом допустимого формата, то этот символ и все последующие символы до следующего символа ‘%’ интерпретируются как последовательность символов, которые игнорируются при их появлении во входном потоке. Если их нет во входном потоке, результат ввода неопределён.

Пример

scanf(“a =%d”, &a);

Во входном потоке может быть a = 123

При выполнении ввода символы a = из входного потока игнорируются, а в качестве значения переменной a введётся значение 123.

Пример Форматный ввод значений из файла

#include <stdio.h>

FILE *f;

void main()

{

int a,e;

float b,d;

char c[17],g, *ft = "a=%d b=%f c =%s%f%d%c";

f=fopen("1.dat","r");

fscanf (f, ft, &a,&b,c,&d,&e,&g);

printf("\na=%d b=%f c =%sd=%fe=%dg=%c",a,b,c,d,e,g);

fclose(f);

}

Содержимое файла “1.dat” с исходными данными

a=123 b=2.5 c=asdfg 3.7 25k

Строка форматов включает подстроки a=, b=, c =. Эти подстроки при считывании данных из файла игнорируются. В результате выполнения программы переменные списка аргументов функции fscanf получают следующие значения:

a=123 b=2.5 c= “asdfg” d = 3.7 e =25 g = ‘k’.

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

Пример

fgets (str, 50, fid);//ввод данных в строку str

sscanf (str, “%d%f%6c%f”, &a,&b,st,&c);//распаковка

Замечание При вводе значений типа float и double функциями sscanf и fscanf возможен неверный ввод, например, в элементы массива структур или элементы массива арифметических данных. Ошибки можно избежать, используя промежуточную скалярную переменную соответствующего типа. Сначала надо ввести значение в эту скалярную переменную, а затем переслать её в элемент массива структур.