scanf 형식 문자열

scanf format string

scanf 형식 문자열(스캔 형식)은 입력 문자열의 레이아웃을 지정하기 위해 다양한 함수에 사용되는 제어 파라미터입니다.이 함수는 문자열을 분할하여 적절한 데이터 유형의 값으로 변환할 수 있습니다.문자열 스캔 기능은 표준 라이브러리에서 제공되는 경우가 많습니다.

"scanf"라는 용어는 이러한 유형의 함수를 대중화한 C 라이브러리에서 유래했지만, 이러한 함수는 C보다 앞서며 다음과 같은 다른 이름이 사용됩니다.readfALGOL 68. 형식화된 입력(파싱)을 제공하는 scanf 형식 문자열은 형식화된 출력(템플릿)을 제공하는 printf 형식 문자열을 보완합니다.이들은 보다 정교하고 유연한 파서 또는 템플릿 엔진과 비교하여 단순한 기능과 고정 형식을 제공하지만 다양한 용도로는 충분합니다.

역사

다음을 포함한 Mike Lesk의 휴대용 입출력 라이브러리scanf공식적으로 [1]버전7에서 Unix의 일부가 되었습니다.

사용.

scanfC에서 수 있는 함수는 표준 입력(대부분 명령줄 인터페이스 또는 유사한 종류의 텍스트 사용자 인터페이스)에서 숫자 및 기타 데이터 유형의 입력을 읽습니다.

다음 C 코드는 표준 입력 스트림에서 다양한 수의 포맷되지 않은 10진수 정수를 읽고 각각 다른 행으로 출력합니다.

#실패하다 <stdio.h>  인트 주된(무효) {     인트 n;      하는 동안에 (스캔(%d, &n) == 1)         인쇄물(%d\n", n);     돌아가다 0; } 

위의 프로그램에 의해 처리된 후 다음과 같은 불규칙한 간격의 정수 목록

456 123 789 456 12 456 1       2378

는 다음과 같이 일정한 간격으로 표시됩니다.

456 123 789 456 12 456 1 2378

단어를 인쇄하려면:

#실패하다 <stdio.h>  인트 주된(무효) {      단어[20];      한다면 (스캔(%19s, 단어) == 1)         놓다(단어);     돌아가다 0; } 

프로그래머가 프로그램에서 읽기를 원하는 데이터 유형에 관계없이 인수(예:&n위)는 메모리를 가리키는 포인터여야 합니다.그렇지 않으면 함수는 입력하려는 변수의 메모리 위치를 가리키는 것이 아니라 잘못된 메모리 섹션을 덮어쓰려고 시도하기 때문에 올바르게 수행되지 않습니다.

마지막 예에서는 주소 연산자(&)는 인수에 사용되지 않습니다.word배열 이름입니다.char따라서 (주소로 평가되는 모든 컨텍스트에서) 어레이의 첫 번째 요소에 대한 포인터와 동일합니다.이 표현은&word는 같은 값으로 수치적으로 평가됩니다.의미적으로는 어레이의 요소가 아니라 어레이 전체의 주소를 나타낸다는 점에서 전혀 다른 의미를 가집니다.할당 시 이 점에 유의해야 합니다.scanf스트링에 출력합니다.

~하듯이scanf표준 입력에서 읽기 전용으로 지정되어 있습니다.PHP와 같은 인터페이스를 가진 많은 프로그래밍 언어에는 다음과 같은 파생 모델이 있습니다.sscanf그리고.fscanf하지만 아니다scanf그 자체입니다.

형식 문자열 사양

의 플레이스 홀더 포맷scanf는 의 역함수와 거의 동일합니다.printf와 마찬가지로 POSIX 확장자는n$정의되어 있습니다.[2]

포맷 문자열에 상수(: 플레이스홀더 포맷이 아닌 문자)가 있는 경우는 거의 없습니다.주로 프로그램이 알려진 데이터를 읽도록 설계되어 있지 않기 때문입니다.scanf는 명시적으로 지정되어 있는 경우는, 이것들을 받아들입니다.하나 이상의 공백 문자는 예외입니다.[2] 입력의 모든 공백 문자는 삭제됩니다.

가장 일반적으로 사용되는 플레이스 홀더는 다음과 같습니다.

  • %a: 부동소수점 숫자를 16진 표기로 스캔합니다.
  • %d: 정수를 부호 있는 10진수로 스캔합니다.
  • %i: 정수를 부호 있는 숫자로 스캔합니다.와 유사하다%d단, 앞에 16진수를 붙이면 16진수로 해석됩니다.0x에 8진수(앞에 있는 경우)를 지정합니다.0예를 들어 문자열은031를 사용하면 31로 인식됩니다.%d, 및 25 (사용)%i. 깃발h%hi로의 변환을 나타냅니다.short그리고.hh로의 변환char.
  • %u: 10진수 스캔unsigned int(C99 규격에서는 입력값 마이너스 부호는 옵션이기 때문에 마이너스 부호를 읽어도 에러는 발생하지 않고, 그 결과 음수(아마도 매우 큰 값)를 2개씩 보완할 수 있습니다.strtoul().)[failed verification] 이에 대응하여%hu의 스캔unsigned short그리고.%hhu잠깐 동안unsigned char.
  • %f: 일반(고정 소수점) 표기의 부동 소수점 숫자를 스캔합니다.
  • %g,%G: 정규 또는 지수 표기로 부동소수점 숫자를 스캔합니다. %g는 소문자를 사용합니다.%G는 대문자를 사용합니다.
  • %x,%X: 부호 없는 16진수로 정수를 스캔합니다.
  • %o: 정수를 8진수로 스캔합니다.
  • %s: 문자열을 스캔합니다.스캔은 공백으로 종료됩니다.문자열 끝에 늘 문자가 저장되어 있습니다.즉, 지정된 입력 길이보다 적어도1글자 긴 버퍼가 필요합니다.
  • %c: 문자(char)를 스캔합니다.null 문자는 추가되지 않았습니다.
  • 공백:공백 문자가 있으면 공백이 0개 이상인 경우 검색이 트리거됩니다.공백 문자의 수와 유형은 어느 방향으로도 일치할 필요가 없습니다.
  • %lf: 더블 부동 소수점 숫자로 스캔합니다."long" 지정자가 있는 "Float" 형식입니다.
  • %Lf: 긴 이중 부동 소수점 숫자로 스캔합니다."float" 형식은 "long long" 지정자입니다.
  • %n: 아무것도 기대되지 않습니다.입력에서 지금까지 사용된 문자 수는 다음 포인터를 통해 저장됩니다. 다음 포인터는 int에 대한 포인터여야 합니다.이것은 변환이 아니며 함수에 의해 반환되는 카운트는 증가하지 않습니다.


위는 숫자 수식어와 조합하여 사용할 수 있습니다.l,L퍼센트 기호와 문자 사이에 있는 "롱"과 "롱롱"을 나타내는 수식어.또한 백분율 기호와 문자 사이에 숫자 값이 있을 수 있습니다.long검색할 문자 수를 지정하는 수식자(있는 경우)를 지정합니다.옵션의 아스타리스크(*percent 기호 바로 뒤에 있는 )는 이 형식 지정자가 읽은 데이터가 변수에 저장되지 않음을 나타냅니다.이 드롭된 변수에는 형식 문자열 뒤에 인수를 포함할 수 없습니다.

ffprintf의 수식자가 scanf에 없으므로 입력 모드와 출력 모드 간에 차이가 발생합니다.ll그리고.hh수식어는 C90 표준에는 없지만 C99 [3]표준에는 있습니다.

형식 문자열의 예는 다음과 같습니다.

"%7d%s %c%lf"

위의 형식 문자열은 처음 7자를 10진수 정수로 스캔한 후 공백, 줄바꿈 또는 탭이 발견될 때까지 나머지 문자를 문자열로 읽은 후 공백이 아닌 첫 번째 문자가 발견될 때까지 공백을 소비한 후 해당 문자를 소비하고 마지막으로 이중으로 스캔합니다.따라서, 강력한 프로그램은 반드시 다음 중 어느 것이 더 나은지 확인해야 합니다.scanf콜이 성공하여 적절한 액션을 수행합니다.입력 형식이 올바르지 않은 경우 잘못된 데이터는 입력 스트림에 계속 존재하므로 새 입력을 읽기 전에 폐기해야 합니다.이를 회피하는 다른 방법은 다음을 사용하는 것입니다.fgets다음으로 읽혀진 문자열을 조사합니다.마지막 단계는 다음과 같이 수행할 수 있습니다.sscanf,예를들면.

플로트 타입의 문자가 많은 경우a, e, f, g의 많은 구현에서는 대부분의 경우 동일한 파서로 압축됩니다.Microsoft MSVCRT는 e, f, [4]g를 사용하고 glibc[2]4가지 모두를 사용합니다.

취약성

scanf는 포맷 문자열 공격에 취약합니다.포맷 문자열에 문자열 및 어레이 크기에 대한 제한이 포함되도록 매우 주의해야 합니다.대부분의 경우 사용자로부터의 입력 문자열 사이즈는 임의이며, 이 사이즈를 판별할 수 없습니다.scanf기능이 실행됩니다.즉, 가 사용하는 것은%s길이 지정자가 없는 플레이스 홀더는 본질적으로 안전하지 않으며 버퍼 오버플로우에 대해 악용될 수 있습니다.또 다른 잠재적인 문제는 설정 파일이나 기타 사용자가 제어하는 파일에 저장된 문자열 형식 지정 등 동적 형식 지정 문자열을 허용하는 것입니다.이 경우 포맷 문자열을 미리 체크하고 제한을 적용하지 않으면 문자열 크기의 허용된 입력 길이를 지정할 수 없습니다.이와 관련하여 실제 변수 목록과 일치하지 않는 형식 지정 자리 표시자가 추가되거나 일치하지 않습니다.이러한 플레이스 홀더는 특정 varargs 구현에 따라 스택에서 부분적으로 추출되거나 바람직하지 않거나 안전하지 않은 포인터가 포함될 수 있습니다.

「 」를 참조해 주세요.

레퍼런스

  1. ^ McIlroy, M. D. (1987). A Research Unix reader: annotated excerpts from the Programmer's Manual, 1971–1986 (PDF) (Technical report). CSTR. Bell Labs. 139.
  2. ^ a b c scanf(3)Linux 프로그래머 매뉴얼– 라이브러리 기능
  3. ^ C99 표준, 제7.19.6.2조 "fscanf 함수" alinea 11.
  4. ^ "scanf Type Field Characters". docs.microsoft.com.

외부 링크