snprintf MAN手冊:
The functions snprintf() and vsnprintf() do not write more than size bytes (including the trailing '\0')
這句話表示snprintf總是會将'\0'寫入。
strncpy MAN手冊:
The strncpy() function is similar, except that not more than n bytes of src are copied. Thus, if there is no null byte among the first n bytes of src, the result will not be null-terminated.
這句話表明如果源字元串比指定的目标長度大,則不會寫入'\0',也就是strncpy總是嚴格尊守指定大小,絕不越雷池半步,也絕不做份外的工作,可以了解成死闆。
從上可以看出,snprintf和strncpy用法稍有不同,分别如下:
char dst[X];
char src[Z];
snprintf(dst, sizeof(dst), "%s", src);
strncpy(dst, src, sizeof(dst)-1);
dst[sizeof(dst)-1] = '\0';
測試代碼:
int main()
{
char dest1[3];
char dest2[3];
char src[] = "0123456789";
printf("src[2]=%d,%c\n", src[2], src[2]);
strncpy(dest1, src, sizeof(dest1)-1);
printf("dest1[2]=%d,%c\n", dest1[2],dest1[2]); // dest1[2]是一個未初始化的随機值
snprintf(dest2, sizeof(dest2), "%s", src);
printf("dest2[2]=%d,%c\n", dest2[2],dest2[2]); // dest2[2]總是一個C字元串結尾符'\0'
return 0;
}
也就是strncpy總是拷貝指定大小的位元組數,絕不會多做,是以不會自動加結尾符'\0',除非指定大小的位元組數範圍内的src已經包含了結尾符'\0'。
但snprintf總是隻拷貝指定大小減1後的位元組數,然後再自動加上結尾符'\0'。是以對于上述strncpy的用法,還應當加上:
dest1[sizeof(dest1)-1] = '\0';
這個時候就正常了,當然也可以:
strncpy(dest1, src, sizeof(dest1)); // 前sizeof(dest1)個位元組,src和dest1将完全相同
dest1[sizeof(dest1)-1] = '\0'; // 将第sizeof(dest1)-1個位元組處置為結尾符'\0'
複制代碼
是以對于strncpy是否需要sizeof()-1,也并非必要的,完全可以隻sizeof(),但一定得再加上結尾符'\0'。
從上也可以看出,不管是strncpy還是snprintf,它們都會尊重sizeof(),都不會向dest拷貝超過sizeof()大小的位元組數。