Для ввода данных в консоли может использоваться функция scanf(). Эта функция определена в заголовочном файле stdio.h (там же, где и функция printf) и имеет следующее формальное определение:
scanf(форматная_строка, аргументы)
И форматная_строка, и аргументы для функции scanf обязательны.
Форматная_строка содержит спецификации преобразования, которые определяют вводимые данные. Общий вид спецификаций преобразования:
% * ширина_поля модификатор спецификатор
Из этих элементов обязательны только два: знак процента % и спецификатор.
Спецификатор определяет тип вводимых данных:
%c: считывает один символ
%d: считывает десятичное целое число
%i: считывает целое число в любой системе (десятичной, шестнадцатеричной, восьмеричной)
%u: считывает положительное целое число
%e: считывает число с плавающей точкой в экспоненциальной форме
%E: считывает число с плавающей точкой в экспоненциальной форме с заглавным символом экспоненты
%f: считывает число с плавающей точкой
%F: считывает число с плавающей точкой
%g: считывает число с плавающей точкой
%G: считывает число с плавающей точкой
%o: считывает восьмеричное число
%x: считывает шестнадцатеричное число
%X: считывает шестнадцатеричное число
%s: считывает строку
%%: считывает символ процента
Символ звездочки * в спецификации преобразования позволяет пропустить при вводе водимые символы для типа, указанного через спецификатор.
Ширина_поля представляет целое положительное число, которое позволяет определить, какое количество байтов будет учитываться при вводе.
Модификаторы позволяют конкретизировать тип данных. В частности, есть следующие модификаторы:
h: для ввода значений типа short int (%hd
)
l: для ввода значений типа long int (%ld
) или double (%lf
, %le
)
L: для ввода значений типа long double (%Lf
, %Le
)
В качестве аргументов в функцию scanf() передаются адреса переменной, которая будет получать введенное значение.
Для получения адреса переменной перед ее именем ставится знак амперсанда &. Например, если переменная называется age
,
то ее адрес мы можем получить с помощью выражения &age
.
Например, введем с консоли числовое значение:
#include <stdio.h> int main(void) { int age; printf("Input your age:"); scanf("%d", &age); printf("age = %d", age); return 0; }
Здесь вводится значение для переменной age, которая представляет тип int, поэтому в форматную строку в функции scanf
передается спецификатор %d. Здесь не используется ни символ звездочки, ни ширина поля, ни модификаторы. Вторым параметром идет
адрес переменной age - &age
.
После ввода значения мы можем его использовать, например, вывести на консоль:
Input your age:44 age = 44
Аналогичен будет ввод данных других типов:
#include <stdio.h> int main(void) { double price; long code; printf("Enter the product code: "); scanf("%ld", &code); printf("Enter the price: "); scanf("%lf", &price); printf("Product code: %ld \t price: %.2lf \n", code, price); return 0; }
После ввода значения мы можем его использовать, например, вывести на консоль:
Enter the product code: 1234 Enter the price: 234.567 Product code: 1234 price: 234.57
Можно сразу вводить несколько значений. В этом случае в качестве разделителя используется пробел:
#include <stdio.h> int main(void) { int count; double price; long code; printf("Enter product data: "); scanf("%ld %d %lf", &code, &count, &price); printf("Product code: %ld \tcount: %d \tprice: %.2lf\n", code, count, price); return 0; }
При вводе данных в консоли функция scanf может использовать пробелы в качестве разделителей, чтобы выдернуть из ввода значения для определенных переменных. Консольный ввод-вывод:
Enter product data: 1234 3 234.56 Product code: 1234 count: 3 price: 234.56
Функция scanf() также позволяет вводить строки. Например:
#include <stdio.h> int main(void) { char name[10]; // вводим имя printf("Enter your name: "); scanf("%10s", name); printf("Name: %s \n",name); return 0; }
Здесь для имени выделяется 10 символов. Теоретически мы можем ввести и большее количество символов, но чтобы только 10 из них учитывались,
в строку форматирования передается ширина поля, которая представляет 10 символов - %10s
. Когда функция считает достаточное количетсво символов, она прекратит считывание.
Обратите внимание, что для ввода строки перед названием переменной не указывается символ адреса.
scanf("%10s", name);
Потому что название массива уже само по себе представляет адрес на первый элемент массива.
Возможный консольный вывод:
Enter your name: Tom Name: Tom
Однако при использовании этой функции мы можем столкнуться с рядом проблем. Прежде всего попробуйте ввести в предыдущем примере составное имя, в которм подстроки разделены пробелами, например, "Tom Smith".
Enter your name: Tom Smith Name: Tom
Для решения этой проблемы можно использовать один хак:
#includeint main(void) { char name[10]; printf("Enter your name: "); scanf("%10[^\n]", name); printf("Name: %s \n",name); return 0; }
Спецификатор %10[^\n]
указавает, что мы по прежнему считываем неболее 10 символов. Квадратные скобки []
представляют
позволяют определить набор символов, которые будут извлекаться из ввода или, наоборот, игнорироваться. Так, выражение [^\n]
говорит,
что надо считать ввод до тех пор пока не встретиться символ перевода строки '\n', то есть пока пользователь не нажмет на клавишу Enter.