Ввод в консоли. Функция scanf

Последнее обновление: 08.01.2023

Для ввода данных в консоли может использоваться функция 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

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

#include 
int 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.

Дополнительные материалы
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850