我在用C语言工作,我必须把一些东西连接起来。
现在我有这个:
message = strcat("TEXT ", var);
message2 = strcat(strcat("TEXT ", foo), strcat(" TEXT ", bar));
现在,如果你有C语言的经验,我相信你会意识到,当你试图运行它时,这会给你一个分割错误。我该怎么做呢?
我在用C语言工作,我必须把一些东西连接起来。
现在我有这个:
message = strcat("TEXT ", var);
message2 = strcat(strcat("TEXT ", foo), strcat(" TEXT ", bar));
现在,如果你有C语言的经验,我相信你会意识到,当你试图运行它时,这会给你一个分割错误。我该怎么做呢?
当前回答
试试类似的方法:
#include <stdio.h>
#include <string.h>
int main(int argc, const char * argv[])
{
// Insert code here...
char firstname[100], secondname[100];
printf("Enter First Name: ");
fgets(firstname, 100, stdin);
printf("Enter Second Name: ");
fgets(secondname,100,stdin);
firstname[strlen(firstname)-1]= '\0';
printf("fullname is %s %s", firstname, secondname);
return 0;
}
其他回答
strcat()的第一个参数需要能够为连接的字符串保留足够的空间。因此,分配一个缓冲区,使其具有足够的空间来接收结果。
char bigEnough[64] = "";
strcat(bigEnough, "TEXT");
strcat(bigEnough, foo);
/* and so on */
Strcat()将第二个参数与第一个参数连接起来,并将结果存储在第一个参数中,返回的char*就是第一个参数,只是为了方便。
您不会得到一个连接第一个和第二个参数的新分配字符串,我猜这是您根据代码所期望的。
避免在C代码中使用strcat。最干净,也是最重要的,最安全的方法是使用snprintf:
char buf[256];
snprintf(buf, sizeof(buf), "%s%s%s%s", str1, str2, str3, str4);
一些评论者提出了一个问题,即参数的数量可能与格式字符串不匹配,代码仍然会被编译,但如果出现这种情况,大多数编译器已经发出警告。
你可以编写自己的函数,做与strcat()相同的事情,但这不会改变任何东西:
#define MAX_STRING_LENGTH 1000
char *strcat_const(const char *str1,const char *str2){
static char buffer[MAX_STRING_LENGTH];
strncpy(buffer,str1,MAX_STRING_LENGTH);
if(strlen(str1) < MAX_STRING_LENGTH){
strncat(buffer,str2,MAX_STRING_LENGTH - strlen(buffer));
}
buffer[MAX_STRING_LENGTH - 1] = '\0';
return buffer;
}
int main(int argc,char *argv[]){
printf("%s",strcat_const("Hello ","world")); //Prints "Hello world"
return 0;
}
如果两个字符串加起来超过1000个字符长,它将在1000个字符处截断字符串。您可以根据需要更改MAX_STRING_LENGTH的值。
您正在尝试将字符串复制到静态分配的地址中。你需要进入缓冲地带。
具体地说:
剪断…
目的地
Pointer to the destination array, which should contain a C string, and be large enough to contain the concatenated resulting string.
剪断…
http://www.cplusplus.com/reference/clibrary/cstring/strcat.html
这里也有一个例子。
假设你有一个char[fixed_size]而不是char*,你可以使用一个单一的,创造性的宏来一次性完成它,使用<<cout<<,比如排序(“而不是%s这个脱节的%s\n”,“而不是”,“printf样式格式”)。如果您正在使用嵌入式系统,此方法还允许您省略malloc和大型*printf函数家族,如snprintf()(这使dietlibc也不会抱怨*printf)
#include <unistd.h> //for the write example
//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[256];
int len=0;
strcpyALL(buf,len,
"The config file is in:\n\t",getenv("HOME"),"/.config/",argv[0],"/config.rc\n"
);
if (len<sizeof(buf))
write(1,buf,len); //outputs our message to stdout
else
write(2,"error\n",6);
//but we can keep adding on because we kept track of the length
//this allows printf-like buffering to minimize number of syscalls to write
//set len back to 0 if you don't want this behavior
strcpyALL(buf,len,"Thanks for using ",argv[0],"!\n");
if (len<sizeof(buf))
write(1,buf,len); //outputs both messages
else
write(2,"error\n",6);
注1,你通常不会像这样使用argv[0]——只是一个例子 注意2,您可以使用输出char*的任何函数,包括用于将整数转换为字符串类型的itoa()等非标准函数。 注意3,如果你已经在程序的任何地方使用了printf,那么没有理由不使用snprintf(),因为编译后的代码会更大(但内联且明显更快)。