scanf() — 데이터 읽기

형식

#include <stdio.h>
int scanf(const char *format-string, argument-list);

언어 레벨

ANSI

스레드세이프

로케일 감지

이 함수의 작동은 현재 로케일의 LC_CTYPE 및 LC_NUMERIC 범주에 영향을 받을 수 있습니다. LOCALETYPE(*LOCALEUCS2) 또는 LOCALETYPE(*LOCALEUTF)가 컴파일 명령에서 지정되면 현재 로케일의 LC_UNI_CTYPE 범주에 영향을 받을 수도 있습니다. 자세한 정보는 CCSID 및 로케일 이해의 내용을 참조하십시오.

설명

scanf() 함수는 표준 입력 스트림 stdin로부터 argument-list에서 각 항목에 의해 지정된 위치로 데이터를 읽습니다 . 각 argumentformat-string에서 양식 지정자에 해당되는 유형을 가진 변수에 대한 포인터여야 합니다. format-string은 입력 필드의 해석을 제어하며 초기 시프트 상태에서 시작하고 끝나는 멀티바이트 문자 스트링입니다.

format-string은 다음 중 하나 이상을 포함할 수 있습니다.
  • 공백 문자로, isspace() 함수(줄 바꾸기 문자와 공백과 같은)에서 지정됩니다. 공백 문자로 scanf() 함수는 공백이 아닌 다음 문자까지 입력의 모든 연속 공백 문자를 읽지만 저장하지 않습니다. format-string의 한 공백 문자는 입력에서 공백 문자의 조합과 일치합니다.
  • 퍼센트 기호 문자(%)를 제외하고, 공백이 아닌 문자입니다. 공백이 아닌 문자로 scanf() 함수는 일치하는 공백이 아닌 문자를 읽지만 저장하지 않습니다. stdin의 다음 문자가 일치하지 않는 경우, scanf() 함수가 종료합니다.
  • 퍼센트 기호(%)로 소개되는 형식 스펙입니다. 형식 스펙으로 scanf() 함수는 입력에서의 문자를 지정된 유형의 값으로 읽습니다. 값은 인수 리스트의 인수에 지정됩니다.

scanf() 함수는 format-string를 왼쪽에서 오른쪽으로 읽습니다. 형식 스펙 외의 문자는 stdin의 문자의 순서와 일치할 것으로 예상합니다. stdin은 스캔되지만 저장되지 않습니다. stdin의 문자가 format-string와 충돌하면, scanf()가 종료됩니다. 충돌되는 문자는 읽히지 않은 것처럼 stdin의 왼쪽에 있습니다.

첫 번째 형식 스펙이 없는 경우, 첫 번째 입력 필드의 값은 형식 스펙에 따라 변환되며 argument-list의 첫 번째 인수로 지정된 위치에 저장됩니다. 두 번째 형식 스펙은 두 번째 입력 필드를 변환하며 format-string의 종료를 통해 두 번째 항목을 argument-list 등에 저장합니다.

입력 필드는 형식 스펙에 따라 변환될 수 없는 첫 번째 문자 또는 필드 width에 도달될 때까지, 어느 것이 먼저 오든 관계없이 모든 문자로 정의됩니다. 형식 스펙보다 더 많은 인수가 있는 경우, 추가 인수는 무시됩니다. 형식 스펙에 인수가 충분하지 않은 경우 결과는 정의되지 않습니다.

형식 스펙의 형식은 다음과 같습니다.

구문 도표 읽기시각적 구문 도표 생략
>>-%--+---+--+-------+--+----+--type---------------------------><
      '-*-'  '-width-'  +-h--+         
                        +-L--+         
                        +-l--+         
                        +-ll-+         
                        +-H--+         
                        +-D--+         
                        '-DD-'         

형식 스펙의 각 필드는 단일 문자이거나 특정 형식 옵션을 지정하는 수입니다. type 문자는 마지막 옵션 형식 필드 다음에 표시되며, 입력 필드가 문자, 스트링 또는 숫자로 해석되는지 여부를 판별합니다. 가장 단순한 형식 스펙은 퍼센트 기호와 type 문자(예: %s)를 포함합니다.

형식 스펙의 각 필드는 아래에서 상세하게 논의됩니다. 퍼센트 기호(%)가 형식 제어 문자로서 의미가 없는 문자 다음에 오면 작동이 정의되지 않습니다. 이 작동에 대한 한 예외는 %%입니다. 퍼센트 기호 문자를 지정하려면, %%을 사용하십시오.

다음 제한사항은 포인터 출력과 스캔에 적용됩니다.
  • 포인터가 동일한 활성 그룹에서 출력되고 다시 스캔되면, 다시 스캔 포인터는 출력된 포인터와 동일하게 비교됩니다.
  • scanf() 제품군 함수가 다른 활성 그룹에서 출력되었던 포인터를 스캔하는 경우, scanf() 제품군 함수는 포인터를 널로 설정합니다.

IBM® i 포인터 사용에 대한 자세한 정보는 ILE C/C++ Programmer's Guide를 참조하십시오.

퍼센트 기호 다음에 오는 별표(*)는 다음 입력 필드의 지정을 생략하며, 지정된 type의 필드로 해석됩니다. 필드는 스캐닝되지만 저장되지 않습니다.

widthstdin에서 읽혀질 최대 개수의 문자를 제어하는 양수의 십진 정수입니다. width 문자 이상은 해당 argument에 변환되고 저장되지 않습니다. width에 도달하기 전에 공백 문자(공백, 탭 또는 줄 바꾸기) 또는 지정된 형식에 따라 변환될 수 없는 문자가 발생하는 경우 width 문자보다 적은 문자가 읽혀집니다.

선택적 크기 수정자 h, l, ll, L, H, D 및 DD는 수신 오브젝트의 크기를 표시합니다. 해당 인수가 int에 대한 포인터가 아닌 short int에 대한 포인터인 경우 변환문자 d, i 및 n은 h보다 앞에 와야 하며, long int에 대한 포인터인 경우 l보다 앞에 와야 하거나, 또는 long long int에 대한 포인터인 경우 ll보다 앞에 와야 합니다. 마찬가지로, 해당 인수가 unsigned int에 대한 포인터가 아닌 unsigned short int에 대한 포인터인 경우 변환문자 o, u, x 및 X는 h보다 앞에 오고, unsigned long int에 대한 포인터인 경우 l보다 앞에 오며 unsigned long long int에 대한 포인터인 경우 ll보다 앞에 와야 합니다. 해당 인수가 float에 대한 포인터가 아닌 double에 대한 포인터인 경우 변환 문자 a, A, e, E, f, F, g 및 G는 l보다 앞에 오고, long double에 대한 포인터인 경우 L보 다 앞에 오고, _Decimal32에 대한 포인터인 경우 H보다 앞에 오고, _Decimal64에 대한 포인터인 경우 D보다 앞에 오거나, 또는 _Decimal128에 대한 포인터인 경우 DD보다 앞에 와야 합니다. 마지막으로 해당 인수가 1바이트 문자 유형에 대한 포인터가 아닌 wchar_t에 대한 포인터인 경우, 변환 문자 c, s 및 [가 앞에 와야 합니다. h, l, L, ll, H, D 또는 DD가 다른 변환 문자와 함께 표시된 경우 기타 작동이 정의되지 않습니다.

type 문자와 해당 의미는 다음 테이블에 있습니다.

문자 예상되는 입력 유형 인수 유형
d 부호가 있는 십진 정수 정수에 대한 포인터
o 부호가 없는 8진 정수 부호가 없는 정수에 대한 포인터.
x, X 부호가 없는 16진 정수 부호가 없는 정수에 대한 포인터.
i 십진, 16진 또는 8진 정수 정수에 대한 포인터
u 부호가 없는 십진 정수 부호가 없는 정수에 대한 포인터
a, A, e, E, f, F, g, G 십진이 아닌 부동 소수점, 선택적으로 부호가 있는 부동 소수점, 무한대 또는 NaN의 경우, 형식은 strtod() 함수에 동일할 것으로 예상합니다.

십진 부동 소수점, 선택적으로 부 호가 있는 부동 소수점, 무한대 또는 NaN의 경우, 형식은 strtod64() 함수와 동일할 것으로 예상합니다.

부동 소수점에 대한 포인터.
D(n,p) 선택적 부호(+ 또는 -), 비어 있지 않은 숫자의 순서, 선택적으로 십진 접미부가 아닌 소수점을 포함하는 하나 이상의 소수점으로 구성되는 팩형 10진수입니다. 주제 시퀀스는 예상 형식에서 첫 번째 비공백 문자로 시작하는 입력 스트링의 가장 긴 초기 시퀀스로 정의됩니다. 입력 스트링이 비어 있거나 공백 전체로 구성된 경우, 또는 첫 번째 비공백 문자가 부호, 숫자 또는 소수점 문자가 아닌 문자인 경우 문자를 포함하지 않습니다. decimal(n,p)에 대한 포인터. 2진 코드화 십진 오브젝트의 내부 표시가 팩형 10진 데이터 유형의 내부 표시와 동일하기 때문에 유형 문자 D(n,p)를 사용할 수 있습니다.
c 문자: c가 지정되면 기본적으로 건너뛴 공백 문자가 읽힙니다. 입력 필드에 충분한 문자에 대한 포인터.
s 스트링 입력 필드 및 끝 널 문자에 충분한 문자 배열에 대한 포인터(\0)로, 자동으로 추가됩니다.
n stream 또는 버퍼에서 읽힌 입력이 없습니다. 정수에 대한 포인터로, scanf()에 대한 호출에서 해당 포인트까지 버퍼나 stream에서 읽힌 문자의 수를 저장합니다.
p 일련의 문자로 변환된 void에 대한 포인터 void에 대한 포인터.
lc 멀티바이트 문자 상수 wchar_t에 대한 포인터.
ls 멀티바이트 스트링 상수 wchar_t 스트링에 대한 포인터.

공백 문자로 구분되지 않는 스트링을 읽으려면, s (string) 유형 문자를 대괄호([ ])의 문자 세트로 대체합니다. 해당 입력 필드는 대괄호 문자 세트에 나타나지 않는 첫 번째 문자까지 읽힙니다. 세트의 첫 번째 문자가 캐럿(^)이면 효과는 반전됩니다. 입력 필드는 문자 세트의 나머지에 나타나는 첫 번째 문자까지 읽힙니다.

끝 널 문자를 저장하지 않고 스트링을 저장하려면(\0), 스펙 %ac를 사용하십시오. 여기서 a는 십진 정수입니다. 이 경우, c 유형 문자는 인수가 문자 배열에 대한 포인터임을 의미합니다. 다음 a 문자는 입력 스트림에서 지정된 위치로 읽히며 추가된 널 문자가 없습니다.

%x 형식 지정자를 위한 입력은 16진수로 해석됩니다.

scanf() 함수는 문자로 각 입력 필드 문자를 스캔합니다. 지정된 width에 도달할거나 다음 문자가 지정된 대로 변환될 수 없는 경우, 공백 문자에 도달하기 전에 특정 입력 필드 읽기를 중단할 수 있습니다. 스펙과 입력 문자 사이에 충돌이 발생하면 다음 입력 필드는 읽지 않은 첫 번째 문자에서 시작합니다. 충돌되는 문자가 하나 있는 경우 읽지 않은 것으로 간주되며 stdin의 후속 읽기 조작에서 첫 번째 문자 또는 다음 입력 필드의 첫 번째 문자입니다.

%lc 및 %ls의 경우, 읽히는 데이터는 멀티바이트 스트링이며 mbtowc에 대한 호출인 것처럼 와이드 문자로 변환됩니다.

%a, %A, %e, %E, %f, %F, %g 및 %G 형식 지정자의 경우, INFINITY 또는 NAN(대소문자 무시)의 문자 시퀀스가 허용되며 각각 INFINITY 또는 Quiet Not-A-Number(NaN)의 값을 양보합니다.

대체 형식 스펙의 양식은 다음과 같습니다.
구문 도표 읽기시각적 구문 도표 생략
>>-%--arg-number$--+---+--+-------+--+----+--type--------------><
                   '-*-'  '-width-'  +-h--+         
                                     +-L--+         
                                     +-l--+         
                                     +-ll-+         
                                     +-H--+         
                                     +-D--+         
                                     '-DD-'         

대안으로서 인수 리스트의 특정 항목은 위의 다이어그램에서 설명한 형식 스펙을 사용하여 지정될 수 있습니다. 이 형식 스펙과 이전 형식 스펙은 scanf()에 대한 동일 호출에서 혼합되지 않을 수 있습니다. 그렇지 않으면, 예측 불가능한 결과가 발생할 수 있습니다.

arg-number는 양의 정수 상수로, 여기서 1은 argument-list의 첫 번째 항목을 참조합니다. 인수 리스트는 인수 리스트의 항목 수보다 크지 않을 수 있거나 결과가 정의되지 않습니다. Arg-number도 NL_ARGMAX보다 크지 않을 수 있습니다.

리턴값

scanf() 함수는 변환되고 지정된 필드 수를 리턴합니다. 리턴값은 읽히지만 지정되지 않은 필드를 포함하지 않습니다.

변환이 수행되지 않은 경우 파일의 끝에서 읽으려는 경우 리턴값은 EOF입니다. 0의 리턴값은 지정된 필드가 없음을 의미합니다.

오류 조건

지정될 인수의 유형이 형식 스펙과 다른 경우, 예측 불가능한 결과가 발생할 수 있습니다. 예를 들면, 부동 소수점 값을 읽지만 변수 유형 int으로 지정하면 부정확하고 예측 불가능한 결과가 생길 수 있습니다.

형식 스펙보다 인수가 많은 경우 추가 인수가 무시됩니다. 형식 스펙에 인수가 충분하지 않은 경우 결과는 정의되지 않습니다.

형식 스트링이 유효하지 않은 형식 스펙을 포함하고 위치 형식 스펙이 사용되면, errno가 EILSEQ로 설정됩니다.

위치 형식 스펙이 사용되고 충분한 인수가 없는 경우, errno는 EINVAL로 설정됩니다.

변환 오류가 발생하면, errnoECONVERT로 설정될 수 있습니다.

이 예는 여러 유형의 데이터를 스캔합니다.
#include <stdio.h>
 
int main(void)
{
   int i;
   float fp;
   char c, s[81];
 
   printf("Enter an integer, a real number, a character "
          "and a string : \n");
   if (scanf("%d %f %c %s", &i, &fp, &c, s) != 4)
      printf("Not all fields were assigned\n");
   else
   {
      printf("integer = %d\n", i);
      printf("real number = %f\n", fp);
      printf("character = %c\n", c);
      printf("string = %s\n",s);
   }
}
 
/*****************  If input is: 12 2.5 a yes,  *******************
**************  then output should be similar to:  ****************
 
Enter an integer, a real number, a character and a string :
integer = 12
real number = 2.500000
character = a
string = yes
*/
이 예는 10진 정수로 16진의 정수를 변환합니다. 입력값이 16진 정수가 아니면 while 루프는 끝납니다.
#include <stdio.h>
 
int main(void)
{
   int number;
 
   printf("Enter a hexadecimal number or anything else to quit:\n");
   while (scanf("%x",&number))
   {
      printf("Hexadecimal Number = %x\n",number);
      printf("Decimal Number     = %d\n",number);
   }
}
 
/***************  If input is: 0x231 0xf5e 0x1 q,  ****************
****************  then output should be similar to:  **************
 
Enter a hexadecimal number or anything else to quit:
Hexadecimal Number = 231
Decimal Number     = 561
Hexadecimal Number = f5e
Decimal Number     = 3934
Hexadecimal Number = 1
Decimal Number     = 1
*/
이 예는 stdin에서 읽고 대체 위치 형식 스트링을 사용하여 데이터를 지정합니다.
#include <stdio.h>
int main(int argc, char *argv[])
{
   int i;
   char s[20];
   float f;

   scanf("%2$s %3$f %1$d",&i, s, &f);

   printf("The data read was \n%i\n%s\n%f\n,i,s,f);

   return 0;
}

/***************  If the input is : test 0.2 100  *****************
**************  then the output will be similar to: ***************
 
The data read was 
100
test
0.20000
*/
 -------------------------------------------------------------------- 
이 예는 멀티바이트 문자 스트링을 와이드 유니코드 스트링으로 읽습니다. LOCALETYPE(*LOCALEUCS2) 또는 LOCALETYPE(*LOCALEUTF)로 예를 컴파일할 수 있습니다.
#include <locale.h>
#include <stdio.h>
#include <wchar.h>

void main(void)
{
   wchar_t uString[20];

   setlocale(LC_UNI_ALL, "");
   scanf("Enter a string %ls",uString);

   printf("String read was %ls\n",uString);
}

/* if the input is : ABC
   then the output will be similiar to:

   String read was ABC

 */