Kernighan과 Pike는 저서 The Practice of Programming (읽을 가치가 있음)에서이 문제를 논의하고 함수 패밀리에 snprintf()
전달할 올바른 버퍼 크기를 가진 문자열을 만드는 데 사용하여 문제를 해결합니다 scanf()
. 사실상:
int scanner(const char *data, char *buffer, size_t buflen)
{
char format[32];
if (buflen == 0)
return 0;
snprintf(format, sizeof(format), "%%%ds", (int)(buflen-1));
return sscanf(data, format, buffer);
}
이것은 여전히 '버퍼'로 제공되는 크기로 입력을 제한합니다. 더 많은 공간이 필요하면 메모리 할당을 수행하거나 메모리 할당을 수행하는 비표준 라이브러리 기능을 사용해야합니다.
참고의 POSIX 2008 (2013) 버전 것으로 scanf()
기능의 가족이 형식 수정 지원 m
문자열 입력에 대한 (할당 할당 문자) ( %s
, %c
, %[
). char *
인수 를받는 대신 char **
인수를 사용하고 읽는 값에 필요한 공간을 할당합니다.
char *buffer = 0;
if (sscanf(data, "%ms", &buffer) == 1)
{
printf("String is: <<%s>>\n", buffer);
free(buffer);
}
은 IF sscanf()
함수는 모든 변환 사양을 만족하지, 모든이에 할당 된 메모리 %ms
-like 변환은 함수가 반환하기 전에 해제됩니다.
buflen-1
합니다. 감사합니다. 그런 다음 서명되지 않은 언더 플로 (다소 많은 수로 래핑)에 대해 걱정해야합니다if
. 나는 그것을으로 대체assert()
하거나 누군가가 크기로 0을 넘길만큼 부주의하다면 개발 중에 발생 하는assert()
이전으로 백업 하고 싶을 것if
입니다. 의%0s
의미 에 대해 문서를주의 깊게 검토하지 않았습니다sscanf()
. 테스트가if (buflen < 2)
.