C library function — sscanf()

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

Каждая из этих функций возвращает количество полей, которые были успешно преобразованы и присвоены; возвращаемое значение не включает поля, которые были считаны, но не были присвоены.Each of these functions returns the number of fields that are successfully converted and assigned; the return value does not include fields that were read but not assigned. Возвращаемое значение 0 указывает, что поля не были назначены.A return value of 0 indicates that no fields were assigned. Возвращаемое значение — EOF для ошибки или, если конец строки достигнут перед первым преобразованием.The return value is EOF for an error or if the end of the string is reached before the first conversion.

Если buffer или Format является пустым указателем, вызывается обработчик недопустимых параметров, как описано в разделе Проверка параметров.If buffer or format is a NULL pointer, the invalid parameter handler is invoked, as described in Parameter Validation. Если выполнение может быть продолжено, эти функции возвращают-1 и устанавливают для еинвал значение.If execution is allowed to continue, these functions return -1 and set errno to EINVAL

Дополнительные сведения об этих и других кодах ошибок см. в разделе errno, _doserrno, _sys_errlist и _sys_nerr.For information about these and other error codes, see errno, _doserrno, _sys_errlist, and _sys_nerr.

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

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

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

  char str30="";
 
  scanf("%", str);
  printf("%s\n", str);

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

  scanf("%", str);
  printf("%s\n", str);

Результат:

Hello, World! 
Hello

Чтение строк

Для чтения из входного потока строки можно использовать функцию scanf() со спецификатором преобразования %s. Использование спецификатора преобразования %s заставляет scanf() читать символы до тех пор, пока не встретится какой-либо разделитель. Читаемые символы помещаются в символьный массив, на который указывает соответствующий аргумент, а после введенных символов еще добавляется символ конца строки (‘0’). Что касается scanf(), то таким разделителем может быть пробел, разделитель строк, табуляция, вертикальная табуляция или подача страницы. В отличие от gets(), которая читает строку, пока не будет нажата клавиша <ENTER>, scanf() читает строку до тех пор, пока не встретится первый разделитель. Это означает, что scanf() нельзя использовать для чтения строки «это испытание», потому что после пробела процесс чтения прекратится. Чтобы увидеть, как действует спецификатор %s, попробуйте при выполнении этой программы ввести строку «привет всем»:

#include <stdio.h>

int main(void)
{
  char str;

  printf("Введите строку: ");
  scanf("%s", str);
  printf("Вот Ваша строка: %s", str);

  return 0;
}

Программа выведет только часть строки, то есть слово привет.

Bugs

All functions are fully C89 conformant, but provide the additional specifiers q and a as well as an additional behavior of the L and
l specifiers. The latter may be considered to be a bug, as it changes the behavior of specifiers defined in C89.

Some combinations of the type modifiers and conversion specifiers defined by ANSI C do not make sense (e.g., %Ld). While they may have a well-defined
behavior on Linux, this need not to be so on other architectures. Therefore it usually is better to use modifiers that are not defined by ANSI C at all, that
is, use q instead of L in combination with d, i, o, u, x, and X conversions or ll.

The usage of q is not the same as on 4.4BSD, as it may be used in float conversions equivalently to L.

NOTES top

   The 'a' assignment-allocation modifier
       Originally, the GNU C library supported dynamic allocation for string
       inputs (as a nonstandard extension) via the a character.  (This
       feature is present at least as far back as glibc 2.0.)  Thus, one
       could write the following to have scanf() allocate a buffer for an
       input string, with a pointer to that buffer being returned in *buf:

           char *buf;
           scanf("%as", &buf);

       The use of the letter a for this purpose was problematic, since a is
       also specified by the ISO C standard as a synonym for f (floating-
       point input).  POSIX.1-2008 instead specifies the m modifier for
       assignment allocation (as documented in DESCRIPTION, above).

       Note that the a modifier is not available if the program is compiled
       with gcc -std=c99 or gcc -D_ISOC99_SOURCE (unless _GNU_SOURCE is also
       specified), in which case the a is interpreted as a specifier for
       floating-point numbers (see above).

       Support for the m modifier was added to glibc starting with version
       2.7, and new programs should use that modifier instead of a.

       As well as being standardized by POSIX, the m modifier has the
       following further advantages over the use of a:

       * It may also be applied to %c conversion specifiers (e.g., %3mc).

       * It avoids ambiguity with respect to the %a floating-point
         conversion specifier (and is unaffected by gcc -std=c99 etc.).

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

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

  int a;
  float b;
  char ch, str30;
 
  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", &a);
  scanf("%f", &b);
  scanf("%c", &ch);
  scanf("%s", str);

Обратите внимание, перед переменной str отсутствует знак амперсанда. Это не опечатка

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

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

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

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

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

Запрет присваивания

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

  float arr3;
  int i;
 
  for(i = ; i < 3; i++)
    scanf("%*s %f", &arri);
 
  printf("Sum: %.2f\n", arr+arr1+arr2);

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

First: 23.356 
Second: 17.285 
Third: 32.457 
Sum: 73.098 
Добавить комментарий

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

Adblock
detector