我知道我不应该使用这个功能,我也不在乎。上次我检查了strcat的规范时,它说了更新第一个值以及返回相同的内容。
现在,这是一个非常愚蠢的问题,我希望你解释一下,就像你和一个非常愚蠢的人说话一样。
为什么这不起作用?
char* foo="foo";
printf(strcat(foo,"bar"));
编辑:我不知道char []和char *之间的区别。我如何分配255个字符的字符串?
编辑2:好的,好的,所以char [number]分配了那么多字节的字符串?说得通。感谢。
编辑3:另外,如何在不声明字符数组的情况下使用字符数组?我会将它作为char [255]进行类型转换吗?
编辑4:strcat((char [256])“foo”,“bar”)返回错误。我对C感到厌烦。
编辑5:strcat((char [256])“foo”,(char [])“bar”也是如此。
编辑5:
char[256] foo="bar";
真正顺利。 “预期的标识符”
答案 0 :(得分:3)
一些问题......
1。
foo
在这里不变。您无法修改字符串文字。
2。
strcat
的合同是第一个参数足够大以适应连接字符串。更现实地说,你会做点什么......
char foo[8] = "foo"; /* Note that buffer size is larger than the string... */
strcat(foo, "bar");
3。
正如你可能猜到的那样,对于一个新手来说,这应该是怎么回事并不明显。我说这是有原因的:一般来说strcat
被认为是非常糟糕的。用于与可能任意长度的缓冲区交互的良好C接口将使这更加明确。您可能希望查看跟踪大小的strncat
或strlcat
。
总的来说,如果你使用的是strcat
家庭,你会做错事。每次调用strcat
都必须遍历字符串以查找结尾的位置。想象一下,你正在进行大量的这些操作 - 很容易想象一些事情很容易在O(n)步骤中突然变成O(n 2 )因为重复遍历串。如果需要重复连接到字符串,则应该维护指向字符串当前末尾的指针并从那里执行复制。
更新:如何执行此最后建议的示例如下......
struct string
{
char *current_end;
size_t bytes_remaining;
};
int
smart_concat(struct string *str, const char *tail)
{
size_t new_length = strlen(tail);
/* Do we have enough space? (include NUL character) */
if (new_length + 1 < str->bytes_remaining)
{
/* Evidently not... */
return -1;
}
/* Copy the string... (including NUL character) */
memcpy(str->current_end, tail, new_length + 1);
/* Update the pointer to the end of our string, and bytes remaining.. */
str->current_end += new_length;
str->bytes_remaining -= new_length;
return 0;
}
然后你可以按如下方式使用它:
struct string str;
char buffer[some_size];
/* Initialize the structure to point at our buffer... */
str.current_end = buffer;
str.bytes_remaining = sizeof(buffer);
/* Strictly speaking, you should check the return code for overflow... */
smart_concat(&str, "foo");
smart_concat(&str, "bar");
/* Print out the result: */
puts(buffer);
答案 1 :(得分:2)
你需要:
字符串常量仅提供文字中的确切内存量,并且不应写入它们。
相反,请执行:
char foo[255] = "foo";
答案 2 :(得分:2)
strcat
非常简单 - 它指向包含字符串和指向另一个字符串的指针的缓冲区,并将第二个字符串复制到已经存在的字符串末尾的缓冲区中。
注意两个参数之间的区别。两者都是char *
,但第一个实际上是指向缓冲区的指针,只是偶然指向字符串的指针(已经在缓冲区中)。作为一个缓冲区,它需要两个简单字符串不能的东西:
在您的示例中,您尝试使用char *foo="foo";
作为第一个参数,但它只是一个字符串,并且缺少缓冲区的两个要求。相反,你需要做类似的事情:
char foo[16] = "foo";
printf(strcat(foo, "bar"));
现在我们将foo
声明为可写char数组,并且有足够的空间来容纳两个字符串 - 一个足够的缓冲区。这就解决了大多数人对strcat的问题,这是上面的第二个要求 - 你怎么知道缓冲区是否有足够的空间?在这样一个简单的例子中,但是对于更复杂的例子(你不一定知道字符串有多长),它变得更加困难。您最终需要跟踪缓冲区的大小,并使用strlen来查看字符串的长度,以确保在调用strcat之前它们是否适合。这既效率低下(最后多次扫描字符串字符串以查找长度然后复制)并且容易出错。
答案 3 :(得分:1)
char* foo="foo";
是一个字符串文字。
无法进行修改。请改为char [] foo = "foo";
,但请记住,使用这样的strcat会在这种情况下导致问题,因为它会在内存中写入时不应该尝试strcat
“bar”所以你应该试试像char foo[30] = "foo";
编辑:你做的类型转换...抱歉,我没有那么多的脑细胞,试图解释你想要做什么。我只能告诉你这是错的。您需要提供内存位置,以便strcat()
可以正常工作。
试试:
int main()
{
char foo[255]="foo";
printf("%s",strcat(foo,"bar"));
}