在使用strncpy, snprintf, strncat時,到底size要定義多大呢?


一、strncpy

char *strncpy(char *dst, const char *src, size_t n);

功能:

        1)把src所指由\0結束的字符串的前n個字節復制到dest所指的數組中。   

        2)返回指向dest的指針(該指向dest的最后一個元素)

說明:

        1)如果src的前n個字節不含\0,則結果不會以\0字符結束(strncpy 並不幫你保證 \0 結束。)。如果src的長度小於n個字節,則以\0填充dst直到復制完n個字節。       

        2)src和dst所指內存區域不可以重疊,且dest必須有足夠的空間來容納src的字符串。  

標准用法:

char buf[80];
strncpy(buf, src, sizeof(buf) - 1);
buf[sizeof(buf) - 1] = '\0';  //手工寫上 \0

問題分析舉例1:

char buf[8];
strncpy( buf, "abcdefgh", sizeof(buf) );

        這個程序里buf 將會被 "abcdefgh" 填滿,但卻沒有 \0 結束符了。

問題分析舉例2:

char buf[80];
strncpy( buf, "abcdefgh", sizeof(buf)-1 );

        如果 src的內容比較少,而 n 又比較大的話,strncpy 將會把之間的空間都用 \0 填充。這就出現了一個效率上的問題,上面的 strncpy 會填寫 79 個 char,而不僅僅是 "abcdefgh" 本身。在對性能要求高的地方使用時,需要考慮該問題。


注:strcpy會拷貝\0

#include <stdio.h>
#include <string.h>

int main()
{
    char a[5];
    int i = 0;
    for (i = 0; i < 5; i++)
    {
        a[i] = -1;
    }

    strcpy(a, "123");
    printf("%c %c %c %d %d\n", a[0], a[1], a[2], a[3], a[4]);
}

輸出:1 2 3 0 -1

二、snprintf

int snprintf(char *str, size_t size, const char *format, ...);

功能:

        將可變個參數(...)按照format格式化成字符串,然后將其復制到str中

說明:

        1)如果格式化后的字符串長度 < size,則將此字符串全部復制到str中,並給其后添加一個字符串結束符('\0');

        2) 如果格式化后的字符串長度 >= size,則只將其中的(size-1)個字符復制到str中,並給其后添加一個字符串結束符('\0'),返回值為欲寫入的字符串長度。

        3)返回值是“如果有足夠空間存儲,所應能輸出的字符數(不包括字符串結尾的'\0')”,例如可以寫入的字符串是"0123456789ABCDEF"共16位,但是size限制了是10,這樣 snprintf() 的返回值將會是16而不是10。

舉例:

char rate[255] = { 0 };
snprintf(rate, sizeof(rate), "%d", 123);

這里size不需要-1,它是字符串拷貝唯一一個會截斷並且會添'\0'的函數

三、strncat

char *strncat(char *dest, const char *src, size_t n);

功能:

        把src所指字符串的前n個字符添加到dest所指字符串的結尾處,從而實現字符串的連接(原dest所指字符串結尾的'\0'將被覆蓋)。如果src字符串長度大於n個字節,那么strncat只截取n個字節,並且會在字符串末尾添加'\0'

說明:

        src和dest所指內存區域不可以重疊,並且dest必須有足夠的空間來容納src的字符串。

返回值:

        返回指向dest的指針。

標准用法:

char buf[256] = { 0 };
strncat(buf,"test",sizeof(buf)-strlen(buf)-1); //如果已知buf長度最好將strlen替代掉,耗性能。

其中sizeof(buf)表示buf的總空間,strlen(buf)表示已經使用的空間,則sizeof(buf)-strlen(buf)-1表示剩余空間大小減一(預留\0的位置,但不需要手動填充)。如果該長度比src長很多,不會像strncpy那樣將\0填充dst直到復制完n個字節。

四、其他

size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);

返回值:

        成功則返回輸出字節數個數,失敗返回0。

        若成功會自動補上'\0'

        默認輸出最大字節為max-1,因此傳入參數時,sizeof 不用再減1。

標准用法:

ret = strftime(buf, sizeof(buf), "%Y-%m-%d", tm);
if(ret == 0){
    printf("failed\n");
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM