snprintf ()는 항상 null로 종료됩니까?
snprintf는 항상 대상 버퍼를 종료하는 null입니까?
즉, 이것으로 충분합니까?
char dst[10];
snprintf(dst, sizeof (dst), "blah %s", somestr);
아니면 somestr이 충분히 길다면 이렇게해야합니까?
char dst[10];
somestr[sizeof (dst) - 1] = '\0';
snprintf(dst, sizeof (dst) - 1, "blah %s", somestr);
나는 표준이 말하는 것과 표준 동작이 아닌 일부 대중적인 libc가 무엇을 할 수 있는지에 관심이 있습니다.
다른 답변이 설정으로 : 그것은 해야한다 :
snprintf
... 결과를 문자열 버퍼에 기록합니다. (...) buf_size가 0이 아니면 널 문자로 종료됩니다.
따라서주의해야 할 것은 크기가 0 인 버퍼를 전달하지 않는 것입니다. 왜냐하면 (분명히) "nowhere"에 0을 쓸 수 없기 때문입니다.
그러나 조심 마이크로 소프트의 라이브러리가
없는 라는 함수를
대신
역사적으로 단지 라는 함수했다 (참고 선도 밑줄) 추가하지 않습니다 종단 널 (null)입니다. 다음은 문서입니다 (VS 2012, ~~ VS 2013) :
snprintf
_snprintf
http://msdn.microsoft.com/en-us/library/2ts7cx93%28v=vs.110%29.aspx
반환 값
len을 형식화 된 데이터 문자열의 길이 (종료 널을 포함하지 않음)로 지정하십시오. len 및 count는 _snprintf의 경우 바이트, _snwprintf의 경우 와이드 문자입니다.
len <count이면 len 문자가 버퍼에 저장되고 널 종료자가 추가되며 len이 리턴됩니다.
len = count이면 len 문자가 버퍼에 저장되고 널 종료자가 추가되지 않으며 len이 리턴됩니다.
len> count이면 count 문자가 버퍼에 저장되고 null 종료자가 추가되지 않고 음수 값이 반환됩니다.
(...)
Visual Studio 2015 (VC14)는 준수 snprintf
기능을 도입 한 것으로 보이지만 선행 밑줄이 있고 null 이 아닌 종료 동작이 있는 레거시 기능 이 여전히 있습니다.
이
snprintf
함수는 len이 count보다 크거나 같을 때 null 종결자를에 배치하여 출력을 자릅니다buffer[count-1]
. (...)모든 함수 다른 보다
snprintf
LEN = 카운트 경우 len 문자가 버퍼에 저장되며, 어떤 널 종결이 추가되지 않는다 (...)
snprintf (3) 맨 페이지에 따름.
함수
snprintf()
및vsnprintf()
최대size
바이트 (후행 널 바이트 ( '\ 0') 포함)를str
.
따라서 크기가 1보다 크면 종료 할 필요가 없습니다.
버퍼 크기는 0, C 않는 표준에 따르면, vsnprintf()
및 snprintf()
널 (null)의 출력을 종료한다.
snprintf()
함수에 상당한다sprintf()
버퍼의 크기 (S)로 지칭 상태 n 인수의 추가. n이 0이면 아무것도 기록되지 않고 s는 널 포인터가 될 수 있습니다. 그렇지 않으면 n-1st 이후의 출력 바이트는 배열에 기록되는 대신 폐기되고 실제로 배열에 기록 된 바이트의 끝에 널 바이트가 기록됩니다.
따라서 할당 할 버퍼의 크기를 알아야하는 경우 0 크기를 사용하고 널 포인터를 대상으로 사용할 수 있습니다. 내가 POSIX 페이지에 링크했지만, 이는 표준 C와 POSIX가 동일한 영역을 다루는 곳에서 차이가 발생하지 않는다고 명시 적으로 말합니다.
이 참조 페이지에 설명 된 기능은 ISO C 표준과 일치합니다. 여기에 설명 된 요구 사항과 ISO C 표준 간의 충돌은 의도하지 않은 것입니다. POSIX.1-2008의이 볼륨은 ISO C 표준을 따릅니다.
Microsoft 버전의 vsnprintf()
. 버퍼에 충분한 공간이 없을 때 표준 C 버전과 확실히 다르게 작동합니다 (표준 함수가 필요한 길이를 반환하는 경우 -1을 반환합니다). 표준 C 버전이 수행하는 반면 Microsoft 버전 null이 오류 조건에서 출력을 종료한다는 것은 명확하지 않습니다.
TR 24731 안전 기능을 사용합니까?에 대한 답변도 참고하십시오 . ( 의 Microsoft 버전 은 MSDN 참조 vsprintf_s()
) 및 안전하지 않은 C 표준 라이브러리 함수에 대한 안전한 대안은 Mac 솔루션입니까?
일부 이전 버전의 SunOS는 snprintf로 이상한 일을했고 출력을 NUL로 종료하지 않았을 수 있고 다른 사람들이하는 일과 일치하지 않는 반환 값을 가지고 있었지만 지난 10 년 동안 릴리스 된 모든 것은 C99를 수행했습니다. 말한다.
모호성은 C 표준 자체에서 시작됩니다. C99와 C11은 모두 동일한 snprintf
기능 설명을 갖습니다 . 다음은 C99의 설명입니다.
7.19.6.5
snprintf
함수
개요
1#include <stdio.h> int snprintf(char * restrict s, size_t n, const char * restrict format, ...);
설명
2 출력이 스트림이 아닌 배열 (인수로 지정됨)에 기록된다는 점을 제외하면 이 함수 는와snprintf
동일 합니다. 경우 IS는 제로, 아무것도 기록되지 않고, 널 포인터가 될 수있다. 그렇지 않으면 st를 초과하는 출력 문자 는 배열에 기록되지 않고 버려지고 실제로 배열에 기록 된 문자의 끝에 널 문자가 기록됩니다. 겹치는 객체간에 복사가 발생하면 동작이 정의되지 않습니다. 반환 3 함수를 작성했다되었을 것입니다 문자 수를 반환fprintf
s
n
s
n-1
snprintf
n
종료 널 문자를 계산하지 않거나 인코딩 오류가 발생한 경우 음수 값을 계산하지 않고 충분히 커야합니다. 따라서 반환 된 값이 음수가 아니고보다 작은 경우에만 null로 끝나는 출력이 완전히 기록되었습니다n
.
한편 으로 문장
그렇지 않으면 st를 초과하는 출력 문자
n-1
는 배열에 기록되지 않고 버려지고 실제로 배열에 기록 된 문자의 끝에 널 문자가 기록됩니다.
says that
if (the s
points to a 3-character-long array, and) n
is 3, then 2 characters will be written, and the characters beyond the 2nd one are discarded; then the null character is written after those 2 (and the null character will be the 3rd character written).
And this I believe answers the original question.
THE ANSWER:
If copying takes place between objects that overlap, the behavior is undefined.
If n
is 0 then nothing is written to the output
otherwise, if no encoding errors encountered, the output is ALWAYS null-terminated (regardless of whether the output fits in the output array or not; if not then some characters are discarded such that the output array is never overflown),
otherwise (if encoding errors are encountered) the output can stay non-null-terminated.
On the other hand
The last sentence
Thus, the null-terminated output has been completely written if and only if the returned value is nonnegative and less than
n
gives ambiguity (or my English is not good enough). I can interpret this sentence in at least two ways:
1. The output is null-terminated if and only if the returned value is nonnegative and less than n
(which means that if the returned value is not less than n
, i.e. the output (including the terminating null character) does not fit in the array, then the output is not null-terminated).
2. The output is complete (no characters have been discarded) if and only if the returned value is nonnegative and less than n
.
I believe that the interpretation 1 above contradicts THE ANSWER, causes misunderstanding and lengthy discussions. That is why the last sentence describing the snprintf
function needs a change in order to remove any ambiguity (which gives grounds for writing a Proposal to the C language Standard).
The example of non-ambiguous wording I believe can be taken from http://en.cppreference.com/w/c/io/fprintf (see 4)
), thanks to @"Martin Ba" for the link.
See also the question "snprintf: Are there any C Standard Proposals/plans to change the description of this func?".
참고URL : https://stackoverflow.com/questions/7706936/is-snprintf-always-null-terminating
'development' 카테고리의 다른 글
Solr에서 "multiValued"필드 유형의 사용은 무엇입니까? (0) | 2020.10.27 |
---|---|
구체적인 클래스에서 상속하는 좋은 예가 있습니까? (0) | 2020.10.27 |
pip는 패키지를 성공적으로 설치하지만 명령 줄에서 찾을 수없는 실행 파일 (0) | 2020.10.27 |
파일 압축에 사용할 무료 라이브러리에 대한 권장 사항 (0) | 2020.10.27 |
Windows 양식 응용 프로그램에서 많은 컨트롤이있는 패널 컨트롤에 스크롤바를 추가하는 방법은 무엇입니까? (0) | 2020.10.27 |