Namespaces
Variants

scanf, fscanf, sscanf, scanf_s, fscanf_s, sscanf_s

From cppreference.net
< c ‎ | io
헤더 파일에 정의됨 <stdio.h>
(1)
int scanf ( const char * format, ... ) ;
(C99 이전)
int scanf ( const char * restrict format, ... ) ;
(C99 이후)
(2)
int fscanf ( FILE * stream, const char * format, ... ) ;
(C99 이전)
int fscanf ( FILE * restrict stream, const char * restrict format, ... ) ;
(C99 이후)
(3)
int sscanf ( const char * buffer, const char * format, ... ) ;
(C99 이전)
int sscanf ( const char * restrict buffer, const char * restrict format, ... ) ;
(C99 이후)
int scanf_s ( const char * restrict format, ... ) ;
(4) (C11 이후)
int fscanf_s ( FILE * restrict stream, const char * restrict format, ... ) ;
(5) (C11 이후)
int sscanf_s ( const char * restrict buffer, const char * restrict format, ... ) ;
(6) (C11 이후)

다양한 소스에서 데이터를 읽어와서 format 에 따라 해석하고 결과를 지정된 위치에 저장합니다.

1) stdin 에서 데이터를 읽습니다
2) 파일 스트림으로부터 데이터를 읽습니다 stream
3) 널 종료 문자열에서 데이터를 읽습니다. buffer 문자열의 끝에 도달하는 것은 fscanf 에 대해 파일 끝 조건에 도달하는 것과 동일합니다.
4-6) (1-3) 와 동일하지만, 다음 예외가 적용됩니다: % c , % s , 및 % [ 변환 지정자 각각이 두 개의 인수(일반적인 포인터와 수신 배열의 크기를 나타내는 rsize_t 타입의 값 - 단일 char에 % c 로 읽을 때는 1 일 수 있음)를 기대하며, 다음 오류들이 런타임에 감지되어 현재 설치된 제약 처리기 함수를 호출한다는 점이 다릅니다:
  • 포인터 타입의 인수 중 하나가 null 포인터인 경우
  • format , stream , 또는 buffer 가 null 포인터인 경우
  • rsize_t ) 인자를 초과하는 경우
  • 선택적으로, 알 수 없는 변환 지정자와 같은 다른 검출 가능한 오류
모든 경계 검사 함수와 마찬가지로, scanf_s , fscanf_s , 및 sscanf_s 는 구현에 의해 __STDC_LIB_EXT1__ 가 정의되고 사용자가 <stdio.h> 를 포함하기 전에 __STDC_WANT_LIB_EXT1__ 를 정수 상수 1 으로 정의한 경우에만 사용 가능함이 보장됩니다.

목차

매개변수

stream - 읽어올 입력 파일 스트림
buffer - 읽어올 널 종료 문자열에 대한 포인터
format - 입력을 읽는 방법을 지정하는 널 종료 문자열에 대한 포인터
... - 수신 인자들


format 문자열은 다음으로 구성됩니다

  • 공백이 아닌 멀티바이트 문자들( % 제외): 형식 문자열 내의 각 해당 문자는 입력 스트림에서 정확히 하나의 동일한 문자를 소비하거나, 스트림의 다음 문자가 동일하지 않을 경우 함수 실패를 유발합니다.
  • 공백 문자: 형식 문자열 내의 단일 공백 문자는 입력에서 사용 가능한 모든 연속 공백 문자들을 소비합니다(루프에서 isspace 를 호출하는 것처럼 결정됨). 형식 문자열에서 " \n " , " " , " \t \t " 또는 기타 공백 사이에는 차이가 없습니다.
  • 변환 지정자. 각 변환 지정자는 다음 형식을 가집니다:
  • 서론 % 문자.
  • (선택적) 할당 억제 문자 * . 이 옵션이 존재하면, 함수는 변환 결과를 어떤 수신 인수에도 할당하지 않습니다.
  • (선택 사항) 0보다 큰 정수로, 현재 변환 지정자에 의해 지정된 변환을 수행할 때 함수가 소비할 수 있는 최대 문자 수인 최대 필드 너비 를 지정합니다. % s % [ 의 경우 너비가 제공되지 않으면 버퍼 오버플로가 발생할 수 있습니다.
  • (선택 사항) 길이 수정자 는 수신 인자의 크기, 즉 실제 대상 유형을 지정합니다. 이것은 변환 정확도와 오버플로우 규칙에 영향을 미칩니다. 기본 대상 유형은 각 변환 유형마다 다릅니다 (아래 표 참조).
  • 변환 형식 지정자.

다음 형식 지정자를 사용할 수 있습니다:

변환
지정자
설명 기대되는
인수 타입
길이 수정자→ hh h 없음 l ll j z t L
C99 이후로만 사용 가능→
%
리터럴 % 와 일치합니다.
N/A N/A N/A N/A N/A N/A N/A N/A N/A
c

문자 또는 문자 시퀀스 와 매치됩니다.

  • 너비 지정자가 사용된 경우, 정확히 width 개의 문자와 매치됩니다 (인자는 충분한 공간을 가진 배열에 대한 포인터여야 합니다).
  • %s 및 %[와 달리 배열에 널 문자를 추가하지 않습니다.
N/A N/A
char *
wchar_t *
N/A N/A N/A N/A N/A
s

공백 문자가 아닌 문자들의 시퀀스(즉, 문자열 )와 매칭됩니다.

  • 너비 지정자가 사용된 경우, width 까지 또는 첫 번째 공백 문자 중 먼저 나타나는 것까지 매칭합니다.
  • 항상 매칭된 문자들에 추가로 널 문자를 저장합니다(따라서 인자 배열은 최소 width+1 개의 문자를 수용할 수 있는 공간이 있어야 합니다).
[ set  ]

set 에 포함된 문자들로 이루어진 비어 있지 않은 문자 시퀀스와 매치됩니다.

  • 집합의 첫 번째 문자가 ^ 인 경우, 집합에 포함되지 않은 모든 문자가 매치됩니다.
  • 집합이 ] 또는 ^] 로 시작하는 경우 ] 문자도 집합에 포함됩니다.
  • 스캔셋에서 처음 위치가 아닌 곳에 있는 - 문자가 [0-9] 와 같은 범위를 나타낼 수 있는지는 구현에 따라 정의됩니다.
  • 너비 지정자가 사용된 경우, 최대 width 까지만 매치됩니다.
  • 매치된 문자들에 추가로 항상 널 문자를 저장합니다(따라서 인수 배열은 최소 width+1 개의 문자를 수용할 수 있어야 합니다).
d

10진수 정수 와 매칭됩니다.

  • 숫자의 형식은 strtol 함수가 10 값을 base 인자로 기대하는 형식과 동일합니다.
signed char * 또는 unsigned char *
signed short * 또는 unsigned short *
signed int * 또는 unsigned int *
signed long * 또는 unsigned long *
signed long long * 또는 unsigned long long *
해당 없음
i

정수 를 매칭합니다.

  • 숫자의 형식은 strtol 함수가 base 인수 값으로 0 을 기대할 때와 동일합니다 (진법은 파싱된 첫 번째 문자들에 의해 결정됨).
u

부호 없는 10진수 정수 와 매칭됩니다.

  • 숫자의 형식은 strtoul 함수가 10 값을 base 인수로 기대하는 형식과 동일합니다.
o

부호 없는 8진수 정수 와 일치합니다.

  • 숫자의 형식은 strtoul 함수에서 8 값을 base 인수로 사용할 때 예상하는 형식과 동일합니다.
x
X

부호 없는 16진수 정수 와 매칭됩니다.

  • 숫자의 형식은 strtoul 함수에서 16 값을 base 인수로 사용할 때 예상되는 형식과 동일합니다.
n

지금까지 읽은 문자 수 를 반환합니다.

  • 입력을 소비하지 않습니다. 할당 횟수를 증가시키지 않습니다.
  • 지정자에 할당 억제 연산자가 정의된 경우, 동작은 정의되지 않습니다.
a (C99)
A (C99)
e
E
f
F (C99)
g
G

부동 소수점 숫자 와 매칭됩니다.

  • 숫자의 형식은 strtof 함수가 기대하는 형식과 동일합니다.
N/A N/A
float *
double *
N/A N/A N/A N/A
long double *
p

구현에서 정의된 포인터를 나타내는 문자 시퀀스와 매칭됩니다.

  • printf 함수군은 %p 형식 지정자를 사용하여 동일한 시퀀스를 생성해야 합니다.
N/A N/A
void **
N/A N/A N/A N/A N/A N/A
참고 사항

n 변환 지정자를 제외한 모든 변환 지정자에 대해, 지정된 필드 너비를 초과하지 않으면서 변환 지정자가 기대하는 시퀀스와 정확히 일치하거나 해당 시퀀스의 접두사인 입력 문자 시퀀스 중 가장 긴 시퀀스가 스트림에서 소비됩니다. 소비된 시퀀스 이후의 첫 번째 문자(있는 경우)는 읽히지 않은 상태로 남습니다. 소비된 시퀀스의 길이가 0이거나 소비된 시퀀스가 위에서 명시된 대로 변환될 수 없는 경우, 스트림에서의 입력을 방해한 파일 끝, 인코딩 오류 또는 읽기 오류가 없는 한 매칭 실패가 발생합니다. 이러한 오류가 발생한 경우에는 입력 실패입니다.

[ , c , n 을 제외한 모든 변환 지정자는 입력을 구문 분석하기 전에 모든 선행 공백 문자( isspace 를 호출하여 결정된 대로)를 소비하고 버립니다. 이러한 소비된 문자는 지정된 최대 필드 너비에 포함되지 않습니다.

변환 지정자 lc , ls , l[ 는 첫 번째 문자가 변환되기 전에 0으로 초기화된 mbstate_t 객체를 사용하여 mbrtowc 를 호출하는 것처럼 멀티바이트-와이드 문자 변환을 수행합니다.

변환 지정자 s [ 는 항상 매칭된 문자에 더해 널 종결 문자를 저장합니다. 대상 배열의 크기는 지정된 필드 너비보다 최소한 1 이상 커야 합니다. 대상 배열 크기를 지정하지 않고 %s 또는 %[ 를 사용하는 것은 gets 만큼 안전하지 않습니다.

고정 너비 정수 타입( int8_t 등)에 대한 올바른 변환 지정자는 <inttypes.h> 헤더에 정의되어 있습니다(비록 SCNdMAX , SCNuMAX 등이 각각 %jd , %ju 등과 동일하지만).

각 변환 지정자의 동작 이후에는 시퀀스 포인트가 존재합니다; 이는 여러 필드를 동일한 "싱크" 변수에 저장하는 것을 허용합니다.

지수 부분만 있고 숫자가 없는 불완전한 부동 소수점 값을 파싱할 때(예: 변환 지정자 %f "100er" 를 파싱하는 경우), "100e" (유효한 부동 소수점 숫자의 가능한 가장 긴 접두사)가 소비되어 매칭 오류(소비된 시퀀스를 부동 소수점 숫자로 변환할 수 없음)가 발생하고 "r" 이 남습니다. 일부 기존 구현체는 이 규칙을 따르지 않고 "100" 만 소비하여 "er" 을 남깁니다(예: glibc 버그 1765).

변환 명세가 유효하지 않은 경우, 동작은 정의되지 않습니다.

변환 지정이 유효하지 않으면, 동작은 정의되지 않습니다.

반환값

1-3) 성공적으로 할당된 수신 인수의 개수 (첫 번째 수신 인수가 할당되기 전에 일치 실패가 발생한 경우에는 0일 수 있음), 또는 EOF 첫 번째 수신 인수가 할당되기 전에 입력 실패가 발생한 경우.
4-6) (1-3) 와 동일하지만, 런타임 제약 조건 위반이 있을 경우 EOF 도 반환됩니다.

복잡도

보장되지 않습니다. 특히, 일부 구현에서는 sscanf O(N) 인 경우가 있으며, 여기서 N = strlen ( buffer ) [1] 입니다.

참고 사항

대부분의 변환 지정자는 먼저 연속된 모든 공백을 소비하기 때문에, 다음과 같은 코드는

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

서로 다른 줄에 입력된 두 정수를 읽을 것입니다(두 번째 % d 가 첫 번째 입력 후 남은 개행 문자를 소비함) 또는 같은 줄에 공백이나 탭으로 구분된 두 정수를 읽을 것입니다(두 번째 % d 가 공백이나 탭을 소비함).

The conversion specifiers that do not consume leading whitespace, such as % c , can be made to do so by using a whitespace character in the format string:
scanf("%d", &a);
scanf(" %c", &c); // %d 이후의 모든 연속 공백 문자를 소비한 후 문자 하나를 읽음

예제

#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
#include <stddef.h>
#include <locale.h>
int main(void)
{
    int i, j;
    float x, y;
    char str1[10], str2[4];
    wchar_t warr[2];
    setlocale(LC_ALL, "en_US.utf8");
    char input[] = "25 54.32E-1 Thompson 56789 0123 56ß水";
    /* 다음과 같이 파싱:
       %d: 정수
       %f: 부동소수점 값
       %9s: 최대 9개의 공백이 아닌 문자로 이루어진 문자열
       %2d: 두 자리 정수 (숫자 5와 6)
       %f:  부동소수점 값 (숫자 7, 8, 9)
       %*d: 어디에도 저장되지 않는 정수
       ' ': 모든 연속된 공백
       %3[0-9]: 최대 3개의 십진 숫자 문자열 (숫자 5와 6)
       %2lc: 2개의 와이드 문자, 멀티바이트에서 와이드 변환 사용  */
    int ret = sscanf(input, "%d%f%9s%2d%f%*d %3[0-9]%2lc",
                     &i, &x, str1, &j, &y, str2, warr);
    printf("Converted %d fields:\n"
           "i = %d\n"
           "x = %f\n"
           "str1 = %s\n"
           "j = %d\n"
           "y = %f\n"
           "str2 = %s\n"
           "warr[0] = U+%x\n"
           "warr[1] = U+%x\n",
           ret, i, x, str1, j, y, str2, warr[0], warr[1]);
#ifdef __STDC_LIB_EXT1__
    int n = sscanf_s(input, "%d%f%s", &i, &x, str1, (rsize_t)sizeof str1);
    // i에 25, x에 5.432, str1에 9바이트 "Thompson\0"을 기록하고 n에 3을 기록
#endif
}

가능한 출력:

Converted 7 fields:
i = 25
x = 5.432000
str1 = Thompson
j = 56
y = 789.000000
str2 = 56
warr[0] = U+df
warr[1] = U+6c34

참조문헌

  • C17 표준 (ISO/IEC 9899:2018):
  • 7.21.6.2 fscanf 함수 (p: 231-236)
  • 7.21.6.4 scanf 함수 (p: 236-237)
  • 7.21.6.7 sscanf 함수 (p: 238-239)
  • K.3.5.3.2 fscanf_s 함수 (p: 430-431)
  • K.3.5.3.4 scanf_s 함수 (p: 432)
  • K.3.5.3.7 sscanf_s 함수 (p: 433)
  • C11 표준 (ISO/IEC 9899:2011):
  • 7.21.6.2 fscanf 함수 (p: 317-324)
  • 7.21.6.4 scanf 함수 (p: 325)
  • 7.21.6.7 sscanf 함수 (p: 326)
  • K.3.5.3.2 fscanf_s 함수 (p: 592-593)
  • K.3.5.3.4 scanf_s 함수 (p: 594)
  • K.3.5.3.7 sscanf_s 함수 (p: 596)
  • C99 표준 (ISO/IEC 9899:1999):
  • 7.19.6.2 fscanf 함수 (p: 282-289)
  • 7.19.6.4 scanf 함수 (p: 290)
  • 7.19.6.7 sscanf 함수 (p: 291)
  • C89/C90 표준 (ISO/IEC 9899:1990):
  • 4.9.6.2 fscanf 함수
  • 4.9.6.4 scanf 함수
  • 4.9.6.6 sscanf 함수

참고 항목

(C99) (C99) (C99) (C11) (C11) (C11)
가변 인수 목록을 사용하여 stdin , 파일 스트림 또는 버퍼에서 형식화된 입력을 읽음
(함수)
파일 스트림에서 문자열을 가져옴
(함수)
stdout , 파일 스트림 또는 버퍼에 형식화된 출력을 인쇄함
(함수)
C++ documentation for scanf , fscanf , sscanf