繁体   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