Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
我只能';我搞不懂strcat_C_String_Char_Strcat - Fatal编程技术网

我只能';我搞不懂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:另外,我如何使

我知道我不应该使用那个函数,我也不在乎。上次我检查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";
真的很顺利。“需要标识符”

是字符串文字

无法对其进行修改。Do
char[]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"));