我目前正在学习C语言,为了更好的学习,我想做的一件事就是模仿头文件中的 "strcat "函数。为了做出更精确的拷贝,我将自己函数的输出与原始函数的输出进行比较。它们使用相同的,但不同的char数组。然而,如果我自己的函数在原始函数之后被调用,它的输出就会改变。下面是两个代码的变化。
在第一段代码中,原函数的输出是: "1234567890123456",正如所料,我自己的输出是 "123456789123456". 在经过几十次的各种检查后,我发现:'0'字符从这个文件中消失了。src[0] 一旦它作为参数被传递给函数,就会被替换掉。
int main()
{
char dest[10] = "123456789";
char src[70] = "0123456";
printf ("Concatenate |%s| and |%s|\n", dest, src);
char dest1[10] = "123456789";
char src1[70] = "0123456";
printf ("Normal people do: %s\n", strcat(dest1, src1));
printf ("Your filthy code: %s\n", ft_strcat(dest, src));
return 0;
}
然而,如果我简单地重新定位函数的printf,就像这样:
int main()
{
char dest[10] = "123456789";
char src[70] = "0123456";
printf ("Concatenate |%s| and |%s|\n", dest, src);
printf ("Your filthy code: %s\n", ft_strcat(dest, src));
char dest1[10] = "123456789";
char src1[70] = "0123456";
printf ("Normal people do: %s\n", strcat(dest1, src1));
return 0;
}
两个函数都会返回 "1234567890123456" 作为输出。
问题是问:这怎么可能?我很好奇,因为这些函数处理的是两组不同的数组,因此不应该相互影响。由于某些原因,我的函数的行为会因在函数的主体中何时被调用而有所不同。int main().
请注意我故意把 dest[]数组做成 10 个大字符,因为我想模仿原来的 "strcat "在意外情况下的行为。虽然这可能是问题的核心,如果我改变它,代码在上述两种情况下都能正常工作。我说过,我感兴趣的是问题的本质,而不是解决问题的方法。
我不知道我的函数的文本是否与这个问题有关,但在这里,以备不时之需。
char *ft_strcat(char *dest, char *src)
{
int dest_end;
int src_count;
dest_end = 0;
src_count = 0;
while (dest[dest_end])
dest_end++;
while (src[src_count])
{
dest[dest_end] = src[src_count];
src_count++;
dest_end++;
}
dest[dest_end + 1] = '\0';
return dest;
}
谢谢你的回答
char dest[10] = "123456789";
char src[70] = "0123456";
printf ("Your filthy code: %s\n", ft_strcat(dest, src));
char dest1[10] = "123456789";
char src1[70] = "0123456";
printf ("Normal people do: %s\n", strcat(dest1, src1));
在这两种情况下,使用自己的函数 ft_strcat(dest, src))
或 strcat()
要么,你调用 未定义行为 因为 char
目的地指向的数组不能容纳初始化的字符串和源指向的附加字符串。当写入超出数组范围的内容时,程序的行为将无法定义。
数组 dest
和 dest1
至少要有 18
元素共。10
用于举办 "0123456789"
, 7
为附加的 "0123456"
+ 1
元素的终端空字符 \0
:
char dest[18] = "123456789";
char dest1[18] = "123456789";
char src[70] = "0123456";
char src1[70] = "0123456";
printf ("Your filthy code: %s\n", ft_strcat(dest, src));
printf ("Normal people do: %s\n", strcat(dest1, src1));
附注:
scr1
是多余的,因为它只用于提供附加字符串,而且它的内容与 src
. 您可以使用 src
对于第二个追加过程,也。printf ("Normal people do: %s\n", strcat(dest1, src));
src
和 src1
各自 70
元素,这是不必要的。它们都只需要有 8
元素,而不是 70
:src[8] = "0123456";
src1[8] = "0123456";
一个更方便的方法是省略元素的数量,让编译器自动检测所需元素的数量,这也保证了你在计数时不会忘记空字符。
src[] = "0123456";
src1[] = "0123456";
src
和其指向的对象都不能在 ft_strcat()
申报 src
作为 char const * const src
.dest
可做 const
也是,但不使它成为指向 const
char: char * const dest
.
你也可以调整 ft_strcat()
关于指针 dest
.
结果是:
char * const ft_strcat(char * const dest, char const * const src)
这是因为内存重叠的缘故... ...因为你声明的大小是... ... dest1[10]
和 dest[10]
而不是像这样声明这两个长度较大的数组。
char dest1[100];
char dest[100];
您的问题将得到解决。