std:: scanf, std:: fscanf, std:: sscanf
|
헤더 파일에 정의됨
<cstdio>
|
||
|
int
scanf
(
const
char
*
format, ...
)
;
|
(1) | |
|
int
fscanf
(
std::
FILE
*
stream,
const
char
*
format, ...
)
;
|
(2) | |
|
int
sscanf
(
const
char
*
buffer,
const
char
*
format, ...
)
;
|
(3) | |
다양한 소스에서 데이터를 읽어와서 format 에 따라 해석하고 결과를 지정된 위치에 저장합니다.
목차 |
매개변수
| stream | - | 입력 파일 스트림 (읽기용) |
| buffer | - | 널 종료 문자열을 읽을 포인터 |
| format | - | 입력 읽기 방식을 지정하는 널 종료 문자열 포인터 |
| ... | - | 수신 인자들 |
format 문자열은 다음으로 구성됩니다
- 공백이 아닌 멀티바이트 문자들 중 % 를 제외한 문자: 형식 문자열 내의 각 해당 문자는 입력 스트림에서 정확히 하나의 동일한 문자를 소비하거나, 스트림의 다음 문자가 동일하지 않을 경우 함수가 실패하게 합니다.
- 공백 문자: 형식 문자열 내의 단일 공백 문자는 입력에서 사용 가능한 모든 연속적인 공백 문자들을 소비합니다(루프에서 std::isspace 를 호출하는 것처럼 결정됨). 형식 문자열에서 " \n " , " " , " \t \t " , 또는 다른 공백 사이에는 차이가 없습니다.
- 변환 지정자. 각 변환 지정자는 다음 형식을 가집니다:
-
- 서론 % 문자.
-
- (선택적) 할당 억제 문자 * . 이 옵션이 존재하면, 함수는 변환 결과를 어떤 수신 인자에도 할당하지 않습니다.
-
- (선택 사항) 0보다 큰 정수로, 현재 변환 지정자에 의해 지정된 변환을 수행할 때 함수가 소비할 수 있는 최대 문자 수인 최대 필드 너비 를 지정합니다. % s 및 % [ 의 경우 너비가 제공되지 않으면 버퍼 오버플로가 발생할 수 있습니다.
-
- (optional) length modifier 수신 인수의 크기, 즉 실제 대상 유형을 지정합니다. 이것은 변환 정확도와 오버플로 규칙에 영향을 미칩니다. 기본 대상 유형은 각 변환 유형에 따라 다릅니다(아래 표 참조).
-
- 변환 형식 지정자.
다음 형식 지정자를 사용할 수 있습니다:
|
변환
지정자 |
설명 |
예상
인수 타입 |
||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| 길이 수정자→ |
hh
|
h
|
없음 |
l
|
ll
|
j
|
z
|
t
|
L
|
|
| C++11부터만 사용 가능→ | Yes | Yes | Yes | Yes | Yes | |||||
%
|
리터럴
%
와 일치합니다.
|
N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A |
c
|
문자 또는 문자 시퀀스 와 매치됩니다.
|
N/A | N/A |
char
*
|
wchar_t
*
|
N/A | N/A | N/A | N/A | N/A |
s
|
공백이 아닌 문자들의 시퀀스(즉, 문자열 )와 매칭됩니다.
|
|||||||||
[
set
]
|
set 에 포함된 문자들로 이루어진 비어 있지 않은 문자 시퀀스와 매치됩니다.
|
|||||||||
d
|
10진수 정수 와 매칭됩니다.
|
signed
char
*
또는
unsigned
char
*
|
signed
short
*
또는
unsigned
short
*
|
signed
int
*
또는
unsigned
int
*
|
signed
long
*
또는
unsigned
long
*
|
signed
long
long
*
또는
unsigned
long
long
*
|
std::
intmax_t
*
또는
std::
uintmax_t
*
|
해당 없음 | ||
i
|
정수 와 매칭됩니다.
|
|||||||||
u
|
부호 없는 10진수 정수 와 매칭됩니다.
|
|||||||||
o
|
부호 없는 8진수 정수 와 매칭됩니다.
|
|||||||||
x
X
|
부호 없는 16진수 정수 와 매칭됩니다.
|
|||||||||
n
|
지금까지 읽은 문자 수 를 반환합니다.
|
|||||||||
a
(C++11)
A
(C++11)
e
E
f
F
(C++11)
g
G
|
부동소수점 숫자 와 매칭됩니다.
|
해당 없음 | 해당 없음 |
float
*
|
double
*
|
해당 없음 | 해당 없음 | 해당 없음 | 해당 없음 |
long
double
*
|
p
|
구현 정의된 문자 시퀀스를 매치하며, 이는 포인터 를 정의합니다.
|
N/A | N/A |
void
**
|
N/A | N/A | N/A | N/A | N/A | N/A |
| 참고 사항 | ||||||||||
|
n 변환 지정자를 제외한 모든 변환 지정자에 대해, 지정된 필드 너비를 초과하지 않으면서 변환 지정자가 기대하는 시퀀스와 정확히 일치하거나 그 시퀀스의 접두사인 입력 문자들의 가장 긴 시퀀스가 스트림에서 소비됩니다. 이렇게 소비된 시퀀스 이후의 첫 번째 문자(있는 경우)는 읽히지 않은 상태로 남습니다. 소비된 시퀀스의 길이가 0이거나 소비된 시퀀스가 위에서 명시된 대로 변환될 수 없는 경우, 매칭 실패가 발생합니다. 단, 스트림에서의 입력이 파일 끝, 인코딩 오류 또는 읽기 오류로 인해 방해받은 경우는 입력 실패입니다. [ , c , 및 n 을 제외한 모든 변환 지정자는 입력을 구문 분석하기 전에 모든 선행 공백 문자들( std::isspace 를 호출하는 것처럼 결정됨)을 소비하고 버립니다. 이러한 소비된 문자들은 지정된 최대 필드 너비에 포함되지 않습니다. 변환 지정자 lc , ls , 및 l [ 는 첫 번째 문자가 변환되기 전에 0으로 초기화된 std::mbstate_t 객체를 사용하여 std::mbrtowc 를 호출하는 것처럼 멀티바이트-와이드 문자 변환을 수행합니다. 변환 지정자 s 와 [ 는 항상 매칭된 문자들에 추가로 널 종결 문자를 저장합니다. 대상 배열의 크기는 지정된 필드 너비보다 최소한 하나 더 커야 합니다. 대상 배열 크기를 지정하지 않고 % s 또는 % [ 를 사용하는 것은 std::gets 와 마찬가지로 안전하지 않습니다. 고정 너비 정수 타입 ( std::int8_t 등)에 대한 올바른 변환 지정자는 헤더 <cinttypes> 에 정의되어 있습니다(비록 SCNdMAX , SCNuMAX 등이 % jd , % ju 등과 동의어이지만). 각 변환 지정자의 동작 이후에는 시퀀스 포인트 가 있습니다; 이는 여러 필드를 같은 "싱크" 변수에 저장할 수 있게 합니다. 지수 부분에 숫자가 없이 끝나는 불완전한 부동 소수점 값을 파싱할 때, 예를 들어 변환 지정자 % f 로 "100er" 를 파싱하는 경우, "100e" (유효한 부동 소수점 숫자의 가능한 가장 긴 접두사) 시퀀스가 소비되어, 매칭 오류(소비된 시퀀스를 부동 소수점 숫자로 변환할 수 없음)가 발생하고, "r" 가 남습니다. 일부 기존 구현체는 이 규칙을 따르지 않고 "100" 만 소비하도록 롤백하여 "er" 를 남깁니다(예: glibc 버그 1765 ). 변환 명세가 유효하지 않은 경우, 동작은 정의되지 않습니다. |
||||||||||
반환값
성공적으로 할당된 수신 인수의 개수(첫 번째 수신 인수가 할당되기 전에 일치 실패가 발생한 경우 0일 수 있음), 또는 EOF 첫 번째 수신 인수가 할당되기 전에 입력 실패가 발생한 경우.
복잡도
보장되지 않습니다. 특히 일부 구현에서는
std::sscanf
가
O(N)
인 경우가 있으며, 여기서
N
=
std::
strlen
(
buffer
)
[1]
입니다. 고성능 문자열 파싱을 위해서는
std::from_chars
를 참조하십시오.
참고 사항
대부분의 변환 지정자는 먼저 연속된 모든 공백을 소비하기 때문에, 다음과 같은 코드는
std::scanf("%d", &a); std::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:std::scanf("%d", &a); std::scanf(" %c", &c); // %d 이후의 개행 문자를 무시하고 문자 하나를 읽습니다
일부
std::sscanf
구현은
std::strlen
호출을 포함하므로, 전체 문자열 길이에 대해 런타임이 선형적으로 증가할 수 있습니다. 이는
std::sscanf
를 반복적으로 호출하여 문자열 앞부분에서 값을 파싱할 경우 코드가 2차 시간에 실행될 수 있음을 의미합니다 (
예시
).
예제
#include <clocale> #include <cstdio> #include <iostream> int main() { int i, j; float x, y; char str1[10], str2[4]; wchar_t warr[2]; std::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: 멀티바이트에서 와이드 문자로 변환하여 두 개의 와이드 문자 const int ret = std::sscanf(input, "%d%f%9s%2d%f%*d %3[0-9]%2lc", &i, &x, str1, &j, &y, str2, warr); std::cout << "Converted " << ret << " fields:\n" "i = " << i << "\n" "x = " << x << "\n" "str1 = " << str1 << "\n" "j = " << j << "\n" "y = " << y << "\n" "str2 = " << str2 << std::hex << "\n" "warr[0] = U+" << (int)warr[0] << "\n" "warr[1] = U+" << (int)warr[1] << '\n'; }
출력:
Converted 7 fields: i = 25 x = 5.432 str1 = Thompson j = 56 y = 789 str2 = 56 warr[0] = U+df warr[1] = U+6c34
참고 항목
|
(C++11)
(C++11)
(C++11)
|
가변 인수 목록을 사용하여
stdin
, 파일 스트림 또는 버퍼에서 형식화된 입력을 읽음
(함수) |
|
파일 스트림에서 문자열을 가져옴
(함수) |
|
|
(C++11)
|
형식화된 출력을
stdout
, 파일 스트림 또는 버퍼에 출력
(함수) |
|
(C++17)
|
문자 시퀀스를 정수 또는 부동 소수점 값으로 변환
(함수) |
|
C 문서
for
scanf
,
fscanf
,
sscanf
|
|