Namespaces
Variants

scanf, fscanf, sscanf, scanf_s, fscanf_s, sscanf_s

cppreference.net에서
< c | io
 
 
파일 입출력
타입 및 객체
        
함수
파일 접근
(C95)
비형식 입출력
(C95)(C95)
(C95)
(C95)(C95)
(C95)
(C95)

형식 입력
 
헤더에 정의됨 <stdio.h>
int scanf( const char* format, ... );
(1) (C99까지)
int scanf( const char* restrict format, ... );
(C99부터)
int fscanf( FILE* stream, const char* format, ... );
(2) (C99까지)
int fscanf( FILE* restrict stream, const char* restrict format, ... );
(C99부터)
int sscanf( const char* buffer, const char* format, ... );
(3) (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로 1을 읽을 때는 %c일 수 있음)를 각각 기대한다는 점과 다음 오류가 런타임에 감지되어 현재 설치된 제약 조건 처리기 함수를 호출한다는 점이 다릅니다.
  • 포인터 타입의 인수 중 하나가 널 포인터인 경우
  • format, stream, buffer가 널 포인터인 경우
  • %c, %s, %[에 의해 쓰여질 문자 수에 종료 널 문자를 더한 값이 각 변환 지정자에 대해 제공된 두 번째(rsize_t) 인수를 초과하는 경우
  • 선택적으로, 알 수 없는 변환 지정자와 같은 기타 감지 가능한 오류
모든 경계 검사 함수와 마찬가지로, scanf_s, fscanf_s, sscanf_s는 구현이 __STDC_LIB_EXT1__을 정의하고 사용자가 __STDC_WANT_LIB_EXT1__을 정수 상수 1으로 정의한 후 <stdio.h>를 포함하는 경우에만 사용 가능함이 보장됩니다.

매개변수

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

문자 또는 문자 시퀀스와 일치합니다.

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

공백이 아닌 문자 시퀀스(문자열)와 일치합니다.

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

집합 내 문자로 구성된 비어 있지 않은 시퀀스와 일치합니다.

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

십진 정수와 일치합니다.

  • 숫자의 형식은 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*
intmax_t* 또는 uintmax_t*
size_t*
ptrdiff_t*
N/A
b (C23)

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

  • 숫자의 형식은 strtoul이 2을 base 인수로 사용할 때 기대하는 형식과 동일합니다.
i

정수와 일치합니다.

  • 숫자의 형식은 strtol이 0을 base 인수로 사용할 때 기대하는 형식과 동일합니다(진수는 구문 분석된 첫 번째 문자에 의해 결정됨).
u

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

  • 숫자의 형식은 strtoul이 10을 base 인수로 사용할 때 기대하는 형식과 동일합니다.
o

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

  • 숫자의 형식은 strtoul이 8을 base 인수로 사용할 때 기대하는 형식과 동일합니다.
x
X

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

  • 숫자의 형식은 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이거나 위와 같이 변환할 수 없는 경우, 파일 끝, 인코딩 오류 또는 읽기 오류로 인해 스트림에서 입력이 차단되지 않는 한 일치 실패가 발생하며, 그렇지 않은 경우 입력 오류입니다.

% 지정자를 제외하고, 입력 항목(또는 %n의 경우 입력 문자 수)은 먼저 변환 지정자에 적합한 타입으로 변환됩니다. *로 할당이 억제되지 않은 경우, 변환 결과는 아직 쓰여지지 않은 다음 인수가 가리키는 객체에 기록됩니다. 이 객체가 적절한 타입이 아니거나 변환 결과를 객체에 표현할 수 없는 경우 동작은 정의되지 않습니다.

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

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

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

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

각 변환 지정자의 작용 후에 시퀀스 포인트가 있습니다. 이를 통해 여러 필드를 동일한 "싱크" 변수에 저장할 수 있습니다.

지수에 숫자가 없이 끝나는 불완전한 부동소수점 값을 구문 분석할 때(예: "100er"을 변환 지정자 %f로 구문 분석), 시퀀스 "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는 공백이나 탭을 소비함)를 읽습니다.

%c와 같이 선행 공백을 소비하지 않는 변환 지정자는 형식 문자열에 공백 문자를 사용하여 선행 공백을 소비하도록 만들 수 있습니다:

scanf("%d", &a);
scanf(" %c", &c); // consume all consecutive whitespace after %d, then read a char

예제

#define __STDC_WANT_LIB_EXT1__ 1
#include <locale.h>
#include <stddef.h>
#include <stdio.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ß水";
    /* parse as follows:
       %d: an integer
       %f: a floating-point value
       %9s: a string of at most 9 non-whitespace characters
       %2d: two-digit integer (digits 5 and 6)
       %f:  a floating-point value (digits 7, 8, 9)
       %*d: an integer which isn't stored anywhere
       ' ': all consecutive whitespace
       %3[0-9]: a string of at most 3 decimal digits (digits 5 and 6)
       %2lc: two wide characters, using multibyte to wide conversion  */
    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);
    // writes 25 to i, 5.432 to x, the 9 bytes "Thompson\0" to str1, and 3 to n.
#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

참조

  • C23 표준 (ISO/IEC 9899:2024):
  • 7.21.6.2 fscanf 함수 (p: TBD)
  • 7.21.6.4 scanf 함수 (p: TBD)
  • 7.21.6.7 sscanf 함수 (p: TBD)
  • K.3.5.3.2 fscanf_s 함수 (p: TBD)
  • K.3.5.3.4 scanf_s 함수 (p: TBD)
  • K.3.5.3.7 sscanf_s 함수 (p: TBD)
  • 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 함수

같이 보기

stdin, 파일 스트림 또는 버퍼에서 가변 인수 목록을 사용하여 형식화된 입력을 읽습니다.

(함수)
파일 스트림에서 문자열을 가져옵니다.
(함수)
stdout, 파일 스트림 또는 버퍼에 형식화된 출력을 인쇄합니다.
(함수)
scanf, fscanf, sscanf에 대한 C++ 문서