簡體   English   中英

在 c 中連接多個字符串的更好方法?

[英]better way to concatenate multiple strings in c?

除了連續多次調用 strcat() 之外,有沒有更好的方法在 c 中將多個字符串連接在一起,如下所示?

char prefix[100] = "";
strcat(prefix, argv[0]);
strcat(prefix, ": ");
strcat(prefix, cmd_argv[0]);
strcat(prefix, ": ");
strcat(prefix, cmd_argv[1]);
perror(prefix);
sprintf(prefix,"%s: %s: %s",argv[0],cmd_argv[0],cmd_argv[1]);

snprintf以防止緩沖區溢出。

snprintf 將是最好和最容易使用的選項,盡管它可能不是“快”。 你沒有 state 你的標准是什么。 不過,簡單性絕對是這樣的:

snprintf(prefix, sizeof(prefix), "%s: %s: %s", argv[0], cmd_argv[0], cmd_argv[1]);

我可能會為此受到打擊,但到底是什么。 可能發生的最糟糕的事情是我會學到一些東西。

這些天我並沒有真正使用 C,而且我通常不會在 C++ 中使用 C 風格的字符串。 但我的一個想法是編寫一個修改后的 strcpy() 來返回字符串的結尾:

char* my_strcpy(char*dest, const char* src)
{
    while ((*dest = *src++))
        ++dest;
    return dest;
}

現在,Shlemiel 可以隨身攜帶他的水桶:

char prefix[100] = "";
char* bucket = my_strcpy(prefix, argv[0]);
bucket = my_strcpy(bucket, ": ");
bucket = my_strcpy(bucket, cmd_argv[0]);
bucket = my_strcpy(bucket, ": ");
bucket = my_strcpy(bucket, cmd_argv[1]);
perror(prefix);

我沒有測試過這個。 注釋?

編輯:刪除了不必要的my_strcat() function。 事實證明它與stpcpy()相同,這顯然是 2008 年 POSIX 的一部分。請參閱http://www.manpagez.com/man/3/stpcpy/

我會像其他人建議的那樣使用sprintf() ,但這是為了完整性:

如果你有stpcpy() ,那么你可以這樣做:

char prefix[100] = "";
stpcpy(stpcpy(stpcpy(sptcpy(stpcpy(prefix, argv[0]), ": "),
        cmd_argv[0]), ": "), cmd_argv[1]);
perror(prefix);

stpcpy()的方便之處在於它可以像上面那樣被“鏈接”。 此外,由於stpcpy()返回指向結果字符串末尾的指針,因此后續stpcpy()調用不需要一次又一次地通過舊數據 go 。 因此,它比多個strcat()更有效,並且可能比sprintf()更有效。 stpcpy()是 POSIX:2008。

假設您發布了 char[fixed_size] 而不是 char*,您可以使用單個創意宏以類似 cout 的順序一次性完成所有操作,而不是脫節的 printf 樣式格式。 如果您正在使用嵌入式系統,此方法將允許您省略大型 printf 系列函數,如snprintf() (這也使 Dietlibc 不會抱怨),甚至不需要malloc()<string.h>

#include <unistd.h> //for write
//note: you should check if offset==sizeof(buf) after use
#define strcpyALL(buf, offset, ...) do{ \
    char *bp=(char*)(buf+offset); /*so we can add to the end of a string*/ \
    const char *s, \
    *a[] = { __VA_ARGS__,NULL}, \
    **ss=a; \
    while((s=*ss++)) \
         while((*s)&&(++offset<(int)sizeof(buf))) \
            *bp++=*s++; \
    if (offset!=sizeof(buf))*bp=0; \
}while(0)

char buf[100];
int len=0;
strcpyALL(buf,len, argv[0],": ", cmd_argv[0],": ",cmd_argv[1]);
if (len==sizeof(buf))write(2,"error\n",6);
else write(1,buf,len); 
  • 注意 1,您可以使用任何輸出 char* 的 function,包括用於將整數轉換為字符串類型的非標准函數,如 itoa()。
  • 注意 2,如果您正在使用共享庫或已經在使用 printf 樣式 function 在靜態構建的程序中的任何位置,那么不使用 snprintf() 的唯一原因(因為使用此方法編譯的代碼會更大)將是因為它是內聯的,不調用任何外部函數,所以應該比較快。

如果您嘗試從其他字符串(您的示例建議)構建一個字符串,那么您可以使用 snprintf。

char prefix[100] = "";
snprintf( prefix, sizeof(prefix), "%s: %s: %s", argv[0], cmd_argv[0], cmd_argv[1]);

如果您嘗試連接現有字符串,而您不能使用格式方法,那么您可能會遇到多次調用 strcat 的問題,盡管我強烈建議您可能要考慮使用strncat並檢查以確保您沒有緩沖區溢出。

你可以使用snprintf function

char prefix[100];
snprintf(prefix, 100, "%s: %s: %s", argv[0], cmd_argv[0], cmd_argv[1]);

你不能用宏。

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

#define a argv[0]
#define b argv[1]
#define c argv[2]
#define strcat1(a,b,c) strcat(prefix, a);\
                       strcat(prefix, ": ");\
                       strcat(prefix, b);\
                       strcat(prefix, ": ");\
                       strcat(prefix, c);\
                       perror(prefix);\



int main(int argc, char *argv[]){
    char prefix[100] = "";
    strcat1(a,b,c);
    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM