我只能';我搞不懂strcat
我知道我不应该使用那个函数,我也不在乎。上次我检查strcat的规范时,它说了一些关于更新第一个值以及返回相同值的内容 现在,这是一个非常愚蠢的问题,我想让你解释一下,就像你在和一个非常愚蠢的人说话一样 为什么这样不行我只能';我搞不懂strcat,c,string,char,strcat,C,String,Char,Strcat,我知道我不应该使用那个函数,我也不在乎。上次我检查strcat的规范时,它说了一些关于更新第一个值以及返回相同值的内容 现在,这是一个非常愚蠢的问题,我想让你解释一下,就像你在和一个非常愚蠢的人说话一样 为什么这样不行 char* foo="foo"; printf(strcat(foo,"bar")); 编辑:我不知道char[]和char*之间的区别。如何分配255个字符的字符串 编辑2:好的,好的,那么char[number]分配了那么多字节的字符串?有道理。谢谢 编辑3:另外,我如何使
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";
真的很顺利。“需要标识符”
是字符串文字
无法对其进行修改。Dochar[]foo=“foo”代码>相反,但请记住,像这样使用strcat会导致问题,在这种情况下,它会在内存中写入它在尝试strcat
“bar”时不应该写入的内容,因此char foo[30]=“foo”代码>
编辑:你所做的打字。。。对不起,我没有那么多的脑细胞来解释你想做什么。我只能告诉你这是错误的。需要提供一个内存位置,以便strcat()
可以工作
试试看:
int main()
{
char foo[255]="foo";
printf("%s",strcat(foo,"bar"));
}
你需要:
- 可写存储器
- 足够的空间
字符串常量只提供文本中确切的内存量,不应该写入
相反,要:
char foo[255] = "foo";
一些问题
一,。
foo
在这里是常量。不能修改字符串文字
二,。
strcat
的约定是第一个参数足够大,可以容纳连接的字符串。所以更现实地说,你应该这样做
char foo[8] = "foo"; /* Note that buffer size is larger than the string... */
strcat(foo, "bar");
三,。
正如你可能猜到的,对于一个新手来说,这是不明显的。我说这是有原因的:一般来说,strcat被认为是相当糟糕的。一个用于与潜在任意长度的缓冲区交互的良好C接口将使这一点更加明确。您可能需要查看strncat
或strlcat
哪些曲目大小
不过,我一般会说,如果你使用的是strcat系列,你就做错了。对strcat的每次调用都必须遍历字符串以找到结束的位置。想象你正在做很多这样的操作——很容易想象一些可以在O(n)步中轻松完成的事情突然变成O(n2),因为字符串的重复遍历。如果需要重复连接到字符串,则应该维护一个指向字符串当前结尾的指针,并从那里进行复制
更新:最后一个建议的示例如下
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;
}
strcat
非常简单——它将指针指向包含一个字符串的缓冲区,并将指针指向另一个字符串,然后将第二个字符串复制到已经存在的字符串末尾的缓冲区中
请注意这两个参数之间的差异。两者都是char*
,但第一个实际上是指向缓冲区的指针,只是顺便说一句,是指向字符串(已经在缓冲区中)的指针。作为缓冲区,它需要两件简单字符串无法做到的事情:
- 它需要是可写的
- 它需要足够的可用空间来容纳复制到其中的第二个字符串
在您的示例中,您尝试使用char*foo=“foo”
作为第一个参数,但它只是一个字符串,缺少对缓冲区的两个要求。相反,您需要执行以下操作:
char foo[16] = "foo";
printf(strcat(foo, "bar"));
现在我们将foo
声明为一个可写的字符数组,有足够的空间来容纳两个字符串——一个足够的缓冲区。这就产生了大多数人在strcat中遇到的问题,这是上面的第二个要求——如何知道缓冲区是否有足够的空间?在这样一个简单的例子中是这样的,但是对于更复杂的例子(你不一定知道字符串有多长),它变得更难了。最后,您需要跟踪缓冲区的大小,并在调用strcat之前使用strlen查看字符串的长度,以确保它们适合。这不仅效率低下(最终需要多次扫描字符串以找到长度,然后进行复制),而且容易出错。但这也不起作用。注意,他做了strcat(foo,…)代码>。如果foo的声明是char foo[]=“foo”代码>那么缓冲区不够大,无法压缩。我不明白字符串文字是什么。字符串文字是否是只能扩展到指定给它的第一个长度的字符串?char[]是动态字符串吗?@asvei,我知道。我在第一次发帖后就考虑过了,并进行了相应的编辑。啊哈!一个字符数组!所以char[255]就是我想要的。谢谢,伙计们。@Anonymous-这个答案很有效,但我鼓励你们也阅读我的答案,了解为什么strcat的性能通常很差。此外,该接口对缓冲区大小也不是很明确,这意味着在使用strcat
时很容易写入安全漏洞和可靠性问题。这是否分配了254个字符的字符串?@Anonymous-它分配了255个字符的数组,索引为0到254。因为C字符串必须以一个终止的空字符结尾,这为长度为254的字符串提供了空间。打字怎么样?我可以使用strcat((char[256])“foo”,“bar”);?强制转换只意味着你在对编译器撒谎。您可能需要编译程序,但仍然没有足够的空间,并且它仍然不在可写段中。情况会更糟。s没有问题
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);
char foo[16] = "foo";
printf(strcat(foo, "bar"));