天天看點

snprintf和strncpy對比

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()大小的位元組數。

繼續閱讀