C语言 在c中连接多个字符串的更好方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5889880/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 08:33:48  来源:igfitidea点击:

better way to concatenate multiple strings in c?

c

提问by user738804

Is there a better way to concatenate multiple strings together in c other than having multiple calls to strcat() all in a row, like below?

除了连续多次调用 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);

回答by Jacob

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

Or snprintfto prevent buffer overruns.

或者snprintf防止缓冲区溢出。

回答by Wes Hardaker

snprintf would be the best and easiest to use option, though it may not be "fast". You didn't state what your criteria was. Simplicity is definitely this, though:

snprintf 将是最好和最容易使用的选项,尽管它可能不是“快速”。你没有说明你的标准是什么。不过,绝对是简单的:

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

回答by Fred Larson

I might take a rep hit for this, but what the heck. The worst thing that can happen is I'll learn something.

我可能会为此受到打击,但这到底是什么。可能发生的最糟糕的事情是我会学到一些东西。

I don't really use C these days, and I don't typically use C-style strings in C++. But one idea I have is to write a modified strcpy() that returns the end of the string:

这些天我并不真正使用 C,而且我通常不在 C++ 中使用 C 样式的字符串。但我的一个想法是编写一个修改后的 strcpy() 来返回字符串的结尾:

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

Now Shlemiel can bring his bucket along with him:

现在 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);

I haven't tested this. Comments?

我没有测试过这个。注释?

EDIT: Removed the unnecessary my_strcat()function. Also it turns out to be the same as stpcpy(), which is apparently part of POSIX as of 2008. See http://www.manpagez.com/man/3/stpcpy/.

编辑:删除了不必要的my_strcat()功能。事实证明stpcpy(),它与 2008 年显然是 POSIX 的一部分相同。请参阅http://www.manpagez.com/man/3/stpcpy/

回答by Alok Singhal

I would use sprintf()like others have suggested, but this is for completeness:

我会sprintf()像其他人建议的那样使用,但这是为了完整性:

If you have stpcpy(), then you can do:

如果你有stpcpy(),那么你可以这样做:

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

The convenience with stpcpy()is that it can be "chained", as above. Also, since stpcpy()returns a pointer to the end of the resultant string, subsequent stpcpy()calls don't need to go through the old data again and again. So, it is more efficient than multiple strcat()s and probably more efficient than sprintf(). stpcpy()is POSIX:2008.

方便之stpcpy()处在于它可以被“链接”,如上所述。此外,由于stpcpy()返回指向结果字符串末尾的指针,因此后续stpcpy()调用不需要一次又一次地遍历旧数据。因此,它比多个strcat()s 更有效,并且可能比sprintf(). stpcpy()是 POSIX:2008。

回答by forsvarir

If you're trying to build a string from other strings (which your example suggests), then you can use snprintf.

如果您试图从其他字符串(您的示例建议)构建一个字符串,那么您可以使用 snprintf。

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

If you're trying to do concatenation of an existing string, where you can't use the format approach, then you're probably stuck with multiple calls to strcat, although I'd strongly suggest that you might want to consider using strncatinstead and checking to ensure you don't have buffer overruns.

如果您尝试连接现有字符串,而您无法使用格式方法,那么您可能会遇到多次调用 strcat,尽管我强烈建议您可能要考虑使用strncat代替和检查以确保您没有缓冲区溢出。

回答by Lucky Murari

you can use snprintffunction

您可以使用snprintf函数

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

回答by technosaurus

Assuming you have a char[fixed_size] as posted, rather than a char*, you can use a single, creative macro to do it all at once with a cout-like ordering rather than the disjointed printf style format. If you are working with embedded systems, this method will allow you to leave out the large printf family of functions like snprintf()(This keeps dietlibc from complaining too) and doesn't even require malloc()or any functions from <string.h>.

假设您发布了一个 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); 
  • Note 1, you can use any function that outputs a char*, including nonstandard functions like itoa() for converting integers to string types.
  • Note 2, if you are using a shared library or are already using a printf style function anywhere in your statically built program, the only reason not to use snprintf() (since the compiled code would be larger with this method) would be that since it is inlined and doesn't call any external functions, so it should be relatively fast.
  • 注意 1,您可以使用任何输出 char* 的函数,包括像 itoa() 这样用于将整数转换为字符串类型的非标准函数。
  • 注意 2,如果您正在使用共享库或已经在静态构建的程序中的任何位置使用 printf 样式函数,那么不使用 snprintf() 的唯一原因(因为使用此方法编译的代码会更大)是因为它是内联的并且不调用任何外部函数,所以它应该是相对较快的。

回答by Lily AB

Couldn't you use a Macro.

你不能用宏。

#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;
}