输出根据函数调用在程序中的位置而改变。

问题描述 投票:0回答:1

我目前正在学习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;
}

谢谢你的回答

c string strcat string.h
1个回答
0
投票
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 目的地指向的数组不能容纳初始化的字符串和源指向的附加字符串。当写入超出数组范围的内容时,程序的行为将无法定义。


解决方法

数组 destdest1 至少要有 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));

附注:

  1. 阵列 scr1 是多余的,因为它只用于提供附加字符串,而且它的内容与 src. 您可以使用 src 对于第二个追加过程,也。
printf ("Normal people do: %s\n", strcat(dest1, src));
  1. srcsrc1 各自 70 元素,这是不必要的。它们都只需要有 8 元素,而不是 70:
src[8] = "0123456";
src1[8] = "0123456";

一个更方便的方法是省略元素的数量,让编译器自动检测所需元素的数量,这也保证了你在计数时不会忘记空字符。

src[] = "0123456";
src1[] = "0123456";
  1. 作为指针 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)

0
投票

这是因为内存重叠的缘故... ...因为你声明的大小是... ... dest1[10]dest[10]而不是像这样声明这两个长度较大的数组。

char dest1[100];
char dest[100];

您的问题将得到解决。

© www.soinside.com 2019 - 2024. All rights reserved.