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에서 데이터를 읽습니다.매개변수
| stream | - | 읽을 입력 파일 스트림 |
| buffer | - | 읽을 널 종료 문자 문자열을 가리키는 포인터 |
| format | - | 입력을 읽는 방법을 지정하는 널 종료 문자 문자열을 가리키는 포인터 |
| ... | - | 수신 인자 |
format 문자열은 다음으로 구성됩니다.
%을 제외한 공백이 아닌 멀티바이트 문자: 형식 문자열의 이러한 각 문자는 입력 스트림에서 정확히 하나의 동일한 문자를 소비하거나, 스트림의 다음 문자가 같지 않으면 함수를 실패하게 합니다.- 공백 문자: 형식 문자열의 단일 공백 문자는 입력에서 사용 가능한 모든 연속 공백 문자를 소비합니다(마치 루프에서 std::isspace를 호출하는 것처럼 결정됨). 형식 문자열에서
"\n"," ","\t\t"또는 기타 공백 문자 간에는 차이가 없습니다. - 변환 지정. 각 변환 지정은 다음 형식을 가집니다:
- 시작
%문자.
- 시작
- (선택사항) 할당 억제 문자
*. 이 옵션이 있으면 함수는 변환 결과를 수신 인자에 할당하지 않습니다.
- (선택사항) 할당 억제 문자
- (선택사항) 최대 필드 너비를 지정하는 (0보다 큰) 정수. 즉, 현재 변환 지정에 의해 지정된 변환을 수행할 때 함수가 소비할 수 있는 최대 문자 수입니다.
%s및%[은 너비가 제공되지 않으면 버퍼 오버플로를 일으킬 수 있습니다.
- (선택사항) 최대 필드 너비를 지정하는 (0보다 큰) 정수. 즉, 현재 변환 지정에 의해 지정된 변환을 수행할 때 함수가 소비할 수 있는 최대 문자 수입니다.
- (선택사항) 길이 수정자: 수신 인자의 크기, 즉 실제 대상 타입을 지정합니다. 이는 변환 정확도와 오버플로 규칙에 영향을 줍니다. 기본 대상 타입은 각 변환 타입마다 다릅니다 (아래 표 참조).
- 변환 형식 지정자.
사용 가능한 형식 지정자는 다음과 같습니다:
| 변환 지정자 |
설명 | 예상 인자 타입 | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| 길이 수정자→ | hh
|
h
|
없음 | l
|
ll
|
j
|
z
|
t
|
L
| |
| C++11부터만 사용 가능→ | 예 | 예 | 예 | 예 | 예 | |||||
%
|
리터럴
%과 일치. |
해당 없음 | 해당 없음 | 해당 없음 | 해당 없음 | 해당 없음 | 해당 없음 | 해당 없음 | 해당 없음 | 해당 없음 |
c
|
문자 하나 또는 문자들의 시퀀스와 일치.
|
해당 없음 | 해당 없음 | char* |
wchar_t* |
해당 없음 | 해당 없음 | 해당 없음 | 해당 없음 | 해당 없음 |
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* |
std::size_t* |
std::ptrdiff_t* |
해당 없음 |
b (C++26)
|
부호 없는 2진 정수와 일치.
| |||||||||
i
|
정수와 일치.
| |||||||||
u
|
부호 없는 10진 정수와 일치.
| |||||||||
o
|
부호 없는 8진 정수와 일치.
| |||||||||
xX
|
부호 없는 16진 정수와 일치.
| |||||||||
n
|
지금까지 읽은 문자 수를 반환합니다.
| |||||||||
a (C++11)A (C++11)eEfF (C++11)gG
|
부동 소수점 숫자와 일치.
|
해당 없음 | 해당 없음 | float* |
double* |
해당 없음 | 해당 없음 | 해당 없음 | 해당 없음 | long double* |
p
|
포인터를 정의하는 구현 정의 문자 시퀀스와 일치.
|
해당 없음 | 해당 없음 | void** |
해당 없음 | 해당 없음 | 해당 없음 | 해당 없음 | 해당 없음 | 해당 없음 |
| 참고 | ||||||||||
|
변환 지정자 변환 지정자 고정 너비 정수 타입 (std::int8_t 등)에 대한 올바른 변환 지정은 헤더 <cinttypes>에 정의되어 있습니다 (SCNdMAX, SCNuMAX 등은 각 변환 지정자의 동작 후에 시퀀스 포인트가 있습니다. 이를 통해 여러 필드를 동일한 "싱크" 변수에 저장할 수 있습니다. 지수가 있고 숫자가 없는 불완전한 부동 소수점 값(예: 변환 지정자 변환 지정이 유효하지 않으면 동작은 정의되지 않습니다. | ||||||||||
반환값
성공적으로 할당된 수신 인자의 수 (첫 번째 수신 인자가 할당되기 전에 일치 오류가 발생한 경우 0일 수 있음), 또는 첫 번째 수신 인자가 할당되기 전에 입력 오류가 발생한 경우 EOF.
복잡도
보장되지 않습니다. 특히 일부 std::sscanf 구현은 O(N)입니다. 여기서 N = std::strlen(buffer) [1]입니다. 성능이 좋은 문자열 구문 분석은 std::from_chars을 참조하십시오.
참고
대부분의 변환 지정자가 먼저 모든 연속 공백을 소비하기 때문에, 다음과 같은 코드는
std::scanf("%d", &a);
std::scanf("%d", &b);
서로 다른 줄에 입력된 두 정수 (두 번째 %d은 첫 번째가 남긴 줄바꿈을 소비함) 또는 공백이나 탭으로 구분된 같은 줄에 입력된 두 정수를 읽습니다 (두 번째 %d는 공백이나 탭을 소비함).
%c와 같이 선행 공백을 소비하지 않는 변환 지정자는 형식 문자열에 공백 문자를 사용하여 그렇게 만들 수 있습니다:
std::scanf("%d", &a);
std::scanf(" %c", &c); // ignore the endline after %d, then read a char
일부 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ß水";
// 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 digits (digits 5 and 6)
// %2lc: two wide characters, using multibyte to wide conversion
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 문서 scanf, fscanf, sscanf
| |