Scanf c что это
Перейти к содержимому

Scanf c что это

  • автор:

Функция scanf

Для считывания данных в языке C используется функция scanf. Ее использование похоже на функцию prinf — сначала задается форматная строка, потом передаются переменные, в которые необходимо записать результат. Например, для считывания двух целых чисел функция вызывается так:

Основное отличие функции scanf в том, что при считывании чисел (или значений типа char) ей необходимо передавать адреса переменных (в языке C все параметры передаются по значению, поэтому чтобы функция scanf могла модифицировать переменную, необходимо передать в функцию адрес этой переменной). Поэтому перед названиями переменных мы пишем знак амперсанда («&»).

В функции scanf могут быть явно записаны какие-то символы, кроме форматных строк. Например, вызов

можно использовать для считывания времени, заданного в виде hh:mm — функция считает число, затем символ двоеточия, затем опять число.

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

Особенности считывания чисел

Функция scanf корректно считывает целые числа, если они начинаются с символа 0, или со знака «+». То есть числа «+123» или «0123» будут корректно считаны по форматной строке «%d», никаких дополнительных параметров задавать не нужно.

Также при считывании чисел игнорируются пробелы перед числом. Это означает, что вызов

scanf(«%d:%d», &a, &b) сможет корректно считать время, заданное в формате hh:mm при наличии пробела после двоеточия (такая запись успешно считает строки «12:34», «01:02», «01:␣23» или «␣01:␣23», поскольку дается указание считать число, затем сразу же двоеточие, затем — число, перед которым могут быть пробелы). Но такая запись не считает выражение, например, вида «01␣:␣23», поскольку после первого числа сразу должно идти двоеточие.

Чтобы считать записать вида «01␣:␣23» можно использовать форматную строку «%d :%d», причем пробел в форматной строке может означать и отсутствие пробелов.

Возможные форматные символы

Возможные форматные символы функции scanf для разных типов данных в целом соответствуют форматным символам для функции printf , но имеют меньше различных модификаторов.

Форматная
строка
Соответствующий ей тип
%hhd Считать число (десятичное) и записать его в переменную типа char (для unsigned char нужно использовать %hhu)
%hd short int (для unsigned short int нужно использовать %hu)
%d int (для unsigned int нужно использовать %u)
%ld long int (для unsigned long int нужно использовать %lu)
%lld long long int (для unsigned long long int нужно использовать %llu)
%f float
%lf double
%Lf long double
char. Считывается один символ, он может быть пробелом или символом конца строки.
%s Считывается последовательность непробельных символов (строка), записывается в C-строку (типа char * или char[])

Особенность считывание символов

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

Особенность считывания строк

При считывании строки результат записывается в С-строку, которая представляет собой массив символов (или указатель типа char * с выделенной памятью). Поскольку строка в языке C является адресом (указателем) в памяти, где хранится начало строки символов, то передавать в функцию scanf нужно имя переменной без указания амперсанда.

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

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

Функция gets считается опасной и не рекомендуется для использования, так как она не контролирует количество считанных символов и не учитывает длину передаваемой строки, что может привести к записи данных за пределами строки.

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

fgets(s, 101, stdin);

В данном случае мы использовали stdin для чтения со стандартного ввода.

Не следует забывать, что в языке C в конец строки добавляется нулевой символ для обозначения конца строки. То есть если необходимо считать строку, в которой может быть 4 символа, то для нее нужно создать массив char[5] , и функции fgets нужно передавать число, не меньшее 5.

Возвращаемое значение

Функция scanf возвращает значение, равное числу успешно считанных и записанных в переданные параметры значений, что можно использовать для анализа входных данных.

Например, пусть вызвали scanf(«%d:%d», &a, &b) .

Тогда при вводе строки «12:34» функция scanf считает два числа, запишет их в переменные a и b и вернет значение 2. А при вводе «12 34» будет считано только одно число, поскольку после него должно идти двоеточие, то второе число считано не будет и функция scanf вернет значение 1.

Форматированный ввод данных в Си — функция scanf

В то время как функция printf() осуществляет форматированный вывод данных, функция scanf() осуществляет их форматированный ввод. Это значит, что поступающие на ввод данные преобразуются соответственно указанному формату(ам) и записываются по адресу(ам) указанной(ых) переменной(ых):

scanf(строка_формата, адреса_переменных);

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

Спецификации, допустимые в строке формата, для scanf() почти идентичны тем, что были описаны для функции printf() .

Ввод чисел, символов и строк

Пример ввода-вывода целого и вещественного чисел, символа и строки:

int a; float b; char ch, str[30]; scanf("%d%f%c%s", &a, &b, &ch, str); printf("%d %.3f %c %s\n", a, b, ch, str);
45 34.3456y hello 45 34.346 y hello

Здесь при выполнении программы все данные были введены в одну строку. Разделителем между числами и строками является пробел, а также любой другой символ пустого пространства (например, ‘\n’). Однако при считывании символа, пробел учитывается как символ; чтобы этого не произошло, в примере букву записали сразу после числа. Данные можно было бы ввести, разделяя их переходом на новую строку (опять же при этом надо иметь ввиду, как считывается символ).

В строке формата функции scanf() между спецификациями вполне допустимо поставить пробелы: %d %f %c %s . Они никакой роли не сыграют. Понятно, что данные можно было получить и так:

scanf("%d", &a); scanf("%f", &b); scanf("%c", &ch); scanf("%s", str);

Обратите внимание, перед переменной str отсутствует знак амперсанда. В последующих уроках вы узнаете, что имя массива уже само по себе является ссылкой на массив (другими словами, str содержит адрес начала массива).

В функции scanf() в спецификации формата вещественных чисел не указывается точность представления числа. Запись типа %.3f или %.10lf приведет к невозможности получить вещественное число. Чтобы получить число типа double используют формат %lf , для long double ‒ %Lf .

Для целых чисел: длинное целое ‒ %ld , короткое целое ‒ %hd . Существуют спецификации для ввода восьмеричных и шестнадцатеричных чисел.

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

int a; double b; char ch, str[30]; ch = scanf("%d %lf %s", &a, &b, str); if (ch == 3) printf("%d %.3lf %s\n", a, b, str); else printf("Error input\n");

Обычные символы в строке формата

В строке формата scanf() допустимо использование обычных символов. В этом случае при вводе данных также должны вводиться и эти символы:

int a, b, c; scanf("%d + %d = %d", &a, &b, &c); printf("Your answer is %d\n", c); printf("The correct is %d\n", a+b);

В данном случае, когда программа выполняется, ввод должен выглядеть примерно так: 342+1024 = 1366. Знаки «+» и » lang»>% , но перед буквой формата звездочку * . В таком случае данные считываются, но никакой переменной не присваиваются. Это можно использовать, например, когда нет определенной уверенности в том, что поступит на ввод, с одной стороны, и нужды сохранять эти данные, с другой:

float arr[3]; int i; for(i = 0; i  3; i++) scanf("%*s %f", &arr[i]); printf("Sum: %.2f\n", arr[0]+arr[1]+arr[2]);

Здесь предполагается, что перед каждым числом будет вводиться строка, которую следует проигнорировать, например:

First: 23.356 Second: 17.285 Third: 32.457 Sum: 73.098

Использование «шаблонов»

Для функции scanf() есть пара спецификаций формата, отдаленно напоминающих шаблоны командной оболочки и др. Формат […] позволяет получить строку, содержащую любые символы, указанные в квадратных скобках. Как только на ввод поступает символ, не входящий в указанный набор, считывание данных прекращается. Формат [^…] , наоборот, помещает в строку символы, не входящие в указанный набор, до тех пор пока не встретит любой из указанных.

В примере ниже как только поступает не цифра, считывание ввода завершается. При этом если первый символ — не цифра, то в str вообще ничего не записывается:

char str[30]=""; scanf("%[0-9]", str); printf("%s\n", str);

А в этом случае строке будет присвоена последовательность символов до любого из указанных знаков препинания:

scanf("%[^;. ]", str); printf("%s\n", str);
one two three four five! one two three four five

Обратите внимание, что в примере выше в строку были записаны как символы пробелов, так и символ перехода на новую строку. Таким образом, если надо прочитать одну строку вместе с пробелами, можно использовать такой подход:

scanf("%[^'\n']", str);

Здесь в строку считываются все символы, кроме перехода на новую строку. Как только встречается этот символ ‒ ‘\n’ , запись данных в переменную прекращается.

Некоторые особенности и ограничения функции scanf

Как только поступают некорректные данные, функция scanf() завершает свою работу. В примере:

scanf("%d%f", &a, &b);

если переменной a попытаться присвоить символ или строку, что невозможно, то в переменную b потом уже не получится записать число. Можно предположить, что так будет надежнее:

scanf("%d", &a); scanf("%f", &b);

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

// если данные не удалось присвоить, if (scanf("%d", &a) != 1) // то выбросить их в виде строки scanf("%*s"); scanf("%f", &b);
  1. На прошлом занятии вы написали программу, содержащую функции, вычисляющие факториал числа и заданный элемент ряда Фибоначчи. Измените эту программу таким образом, чтобы она запрашивала у пользователя, что он хочет вычислить: факториал или число Фибоначчи. Затем программа запрашивала бы у пользователя либо число для вычисления факториала, либо номер элемента ряда Фибоначчи.
  2. Напишите программу, которая запрашивает у пользователя две даты в формате дд.мм.гггг. Дни, месяцы и года следует присвоить целочисленным переменным. Программа должна выводить на экран информацию о том, какая дата более ранняя, а какая более поздняя.
  3. Используя цикл, напишите код, в котором пользователю предлагается вводить данные до тех пор, пока он не сделает это корректно, т.е. пока все указанные в scanf() переменные не получат свои значения. Протестируйте программу.

Курс с решением задач:
pdf-версия

Функция scanf() в СИ: определение, примеры, применение, таблица

Lorem ipsum dolor

В функциональности этих функций нет никакой разницы, просто scanf() появилась в первых версиях языка С, поэтому считается менее защищенной. Обычно при работе с о scanf() в современных компиляторах требуется наличие строки «#define _CRT_SECURE_NO_WARNINGS» в кодовом документе.

Либо можно применять усовершенствованную функцию scanf_s(), которая считается уже защищенной и не требует наличия вышеописанной строки.

Заключение

В программах информация не только выводится, но и принимается. Теперь вы знаете, что при помощи функции scanf() в Си можно принять любые данные, главное — правильно обозначить спецификатор. Немного потренировавшись, вы поймете , что с функцией «сканф» в Си работать не сложнее , чем с функцией printf() в этом же языке.

Мы будем очень благодарны

если под понравившемся материалом Вы нажмёте одну из кнопок социальных сетей и поделитесь с друзьями.

scanf в C/C++: простыми словами с таблицей

�� Рад вас видеть! В этой статье мы поговорим о функции scanf . Начнем мы с простого примера для разогрева. Потом мы рассмотрим все спецификаторы формата, которые эта функция поддерживает. Знание printf будет большим плюсом при знакомстве со scanf . В конце статьи вы найдете несколько упражнений для закрепления материала.

Иллюстрация scanf

Как считывать данные используя scanf

Для считывания данных из стандартного ввода в C и C++ можно воспользоваться функцией scanf . Эта функция доступна нам после подключения заголовочного файла (в C++ я рекомендую использовать ).

Функция scanf имеет следующий вид:

int scanf ( const char * format, ... );
  • Первым аргументом передается строка, которая описывает формат строки, которую мы будем считывать.
  • Вторым и последующими аргументами передаются параметры, которые ожидает функция scanf на основе переданного формата строки (первого аргумента).
  • Возвращает функция количество считанных аргументов. scanf может считать меньше указанного количества значений (вплоть до нуля), поскольку возможны ошибки и неожиданные символы при вводе.

Давайте теперь посмотрим на пример использования этой функции:

#include int main()  int i; char name[10]; char c; printf("Загадайте число: "); scanf("%d", &i); printf("Звезды говорят что вы загадали %d\n", i); printf("Теперь введите имя и год рождения через пробел: "); int n = scanf("%s %d", name, &i); printf("Значений считано: %d\n", n); printf("%s, ваш приз без регистрации: $%d", name, i * 2); return 0; >

Пример работы программы:

Загадайте число: 42 Звезды говорят что вы загадали 42 Теперь введите имя и год рождения через пробел: Дима 1999 Значений считано: 2 Дима, ваш приз без регистрации: $3998

scanf игнорирует пробельные символы в начале при считывании.

В этой программе мы продемонстрировали, как можно использовать scanf для простого ввода. Давайте попробуем считать что-то посложнее:

#include int main()  int day, year; char month[20]; float price; printf("Введите дату, название месяца и цену (например, 15 Август 2023 $10.50): "); int n = scanf("%d %s %*d $%f", &day, month, &price); printf("День: %d\n", day); printf("Месяц: %s\n", month); printf("Цена: %.2f\n", price); printf("Значений считано: %d\n", n); return 0; >

scanf считывает строки %s до первого пробельного символа.

Пример работы программы:

Введите дату, название месяца и цену (например, 15 Август 2023 $10.50): 17 Июль 2010 $12.34 День: 17 Месяц: Июль Цена: 12.34 Значений считано: 3
  • Мы используем %*d для игнорирования года. Звездочка говорит scanf ‘у считать, но не сохранять значение.
  • Мы считываем день в day , строку в month и цену в price .
  • scanf возвращает количество успешно считанных аргументов, т.е. 3, потому что одно значение было проигнорировано.

Теперь давайте разберем все спецификаторы формата, которые можно использовать для считывания значений.

Certainly, here is the modified question with the changes you requested:

Какой будет вывод программы, если пользователь введет 10 20 30.50 ?

#include int main()  int a; float c; int n = scanf("%d %*d %f", &a, &c); printf("a: %d, c: %.2f, n: %d\n", a, c, n); return 0; >

a: 10, c: 30.50, n: 3
a: 10, c: 30.50, n: 2
a: 10, c: 20.00, n: 2
a: 10, c: 30.50, n: 1

Функция scanf считывает значения в переменные a и c , но значение 20 игнорируется из-за спецификатора формата %*d , который говорит scanf считать, но не сохранять значение. Поэтому, scanf вернет 2 (количество успешно считанных аргументов).

Структура спецификатора в scanf немного отличается от спецификатора в printf (в квадратных скобках опциональные модификаторы):

%[*][ширина][размер]тип

Как видите, обязательными являются только знак процента и тип; остальные можно не использовать.

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

scanf(«%i», &x); // x = 987
scanf(«%i», &x); // x = -987
scanf(«%i», &x); // x = 987

Считывает целое число в десятеричной системе.

scanf(«%d», &x); // x = -987

Считывает целое положительное число в десятеричной системе.

scanf(«%u», &x); // x = 987

Считывает целое число в восьмеричной системе.

scanf(«%o», &x); // x = -987

Считывает целое число в шестнадцатеричной системе.

scanf(«%x», &x); // x = -987
scanf(«%x», &x); // x = 987

Считывает вещественное число.

scanf(«%f», &x); // x = 12.34
scanf(«%f», &x); // x = 12.34
scanf(«%f», &x); // x = 12.34
scanf(«%f», &x); // x = 12.34

1.234e+01
12.34
987
0x1.8ap+3

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

Считывает адрес в памяти.

scanf(«%p», &x); // x = 0x16dc

Считывает строку до тех пор, пока не встретит символ, который отличается от символов, внутри квадратных скобок.

Считывает строку до тех пор, пока не встретит символ, который совпадает с одним из символов, внутри квадратных скобок, после ^ .

Ничего не считывает. Записывает количество считанных символов до этого момента.

scanf(«C++%n11», &x); // x = 3

Считывает знак процента.

Мы можем указать звездочку после процента, чтобы не сохранять прочитанное значение:

int x; scanf("Пропустить: %*d, сохранить: %d", &x); printf("Число: %d", x);
Пропустить: 123, сохранить: 456 Число: 456

Звездочку можно использовать с любым типом из таблицы выше, не только с числами.

Мы можем указать максимальное количество символов, которые будут прочитаны функцией scanf при считывании значения:

char s[4]; // 3 символа + '\0' scanf("%3s", s); printf("Считали: %s", s);
C++11 Считали: C++

Как и звездочка, ширину можно указывать для любого типа.

По умолчанию, scanf считывает значения типа int , unsigned int , float и char (зависит от типа спецификатора). Чтобы считать, например, значение в переменную типа long long int , нам нужно явно указать размер:

#include #include int main()  long long int x; printf("Число: "); scanf("%lld", &x); // ^ добавили ll для long long int printf("Считали: %lld\n", x); // ^ в printf тоже не забываем return 0; >
Число: 10000000000 Считали: 10000000000

Без указания размера вывод будет выглядеть примерно так:

Число: 10000000000 Считали: 5705032704

Мы видим такой вывод, потому что десять миллиардов просто не влезают в тип int , который scanf пытается считать без явного указания размера.

Вот таблица размеров, которые можно использовать:

signed char / unsigned char

short int / unsigned short int

long int / unsigned long int

long long int / unsigned long long int

  1. Игнорирование значений:
    Напишите программу на C++, которая запрашивает у пользователя дату (день, месяц, год), но сохраняет только день и месяц, игнорируя год. Используйте спецификатор %*d для игнорирования значения года. После ввода пользователем данных, программа должна выводить сохраненные значения дня и месяца.
  2. Считывание различных типов данных:
    Создайте программу, которая запрашив

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *