我在用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语言的经验,我相信你会意识到,当你试图运行它时,这会给你一个分割错误。我该怎么做呢?
当前回答
如果你有C语言的经验,你会注意到字符串只是字符数组,其中最后一个字符是空字符。
现在这是相当不方便的,因为你必须找到最后一个字符,以追加一些东西。Strcat会帮你的。
所以strcat通过第一个参数搜索空字符。然后它将用第二个参数的内容替换它(直到它以null结束)。
现在让我们看一下你的代码:
message = strcat("TEXT " + var);
在这里,您向指向文本“text”的指针添加了一些内容(“text”的类型是const char*。一个指针)。
这通常是行不通的。此外,修改“TEXT”数组也将不起作用,因为它通常被放置在常量段中。
message2 = strcat(strcat("TEXT ", foo), strcat(" TEXT ", bar));
这可能会工作得更好,除非您再次尝试修改静态文本。Strcat没有为结果分配新的内存。
我建议这样做:
sprintf(message2, "TEXT %s TEXT %s", foo, bar);
阅读sprintf的文档,检查它的选项。
现在有一点很重要:
确保缓冲区有足够的空间容纳文本和空字符。有几个函数可以帮助您,例如strncat和printf的特殊版本,它们为您分配缓冲区。 不确保缓冲区大小将导致内存损坏和可远程利用的错误。
其他回答
strcat()的第一个参数需要能够为连接的字符串保留足够的空间。因此,分配一个缓冲区,使其具有足够的空间来接收结果。
char bigEnough[64] = "";
strcat(bigEnough, "TEXT");
strcat(bigEnough, foo);
/* and so on */
Strcat()将第二个参数与第一个参数连接起来,并将结果存储在第一个参数中,返回的char*就是第一个参数,只是为了方便。
您不会得到一个连接第一个和第二个参数的新分配字符串,我猜这是您根据代码所期望的。
字符串也可以在编译时进行连接。
#define SCHEMA "test"
#define TABLE "data"
const char *table = SCHEMA "." TABLE ; // note no + or . or anything
const char *qry = // include comments in a string
" SELECT * " // get all fields
" FROM " SCHEMA "." TABLE /* the table */
" WHERE x = 1 " /* the filter */
;
尝试修改字符串字面量是未定义的行为,这是类似于:
strcat ("Hello, ", name);
会尝试去做。它将尝试将名称字符串附加到字符串字面量“Hello,”的末尾,这没有很好地定义。
试试这个。它达到了你想要达到的效果:
char message[1000];
strcpy (message, "TEXT ");
strcat (message, var);
这将创建一个允许修改的缓冲区,然后将字符串字面量和其他文本复制到该缓冲区。只是要小心缓冲区溢出。如果您控制输入数据(或事先检查),可以使用像我这样的固定长度的缓冲区。
否则,您应该使用缓解策略,例如从堆中分配足够的内存以确保可以处理它。换句话说,就像:
const static char TEXT[] = "TEXT ";
// Make *sure* you have enough space.
char *message = malloc (sizeof(TEXT) + strlen(var) + 1);
if (message == NULL)
handleOutOfMemoryIntelligently();
strcpy (message, TEXT);
strcat (message, var);
// Need to free message at some point after you're done with it.
避免在C代码中使用strcat。最干净,也是最重要的,最安全的方法是使用snprintf:
char buf[256];
snprintf(buf, sizeof(buf), "%s%s%s%s", str1, str2, str3, str4);
一些评论者提出了一个问题,即参数的数量可能与格式字符串不匹配,代码仍然会被编译,但如果出现这种情况,大多数编译器已经发出警告。
另外,如果您不知道要连接多少字符串,malloc和realloc也很有用。
#include <stdio.h>
#include <string.h>
void example(const char *header, const char **words, size_t num_words)
{
size_t message_len = strlen(header) + 1; /* + 1 for terminating NULL */
char *message = (char*) malloc(message_len);
strncat(message, header, message_len);
for(int i = 0; i < num_words; ++i)
{
message_len += 1 + strlen(words[i]); /* 1 + for separator ';' */
message = (char*) realloc(message, message_len);
strncat(strncat(message, ";", message_len), words[i], message_len);
}
puts(message);
free(message);
}