char 数组的最后一个值未知 - C

Last value of char array unknown - C

我正在用 C 编写一个简单的程序,它检查某个 char 数组的长度,如果它小于 8,我想用零填充一个新数组并将其添加到前一个数组中。问题来了。我不知道为什么最后的值是一些标志(见照片)。

char* hexadecimalno = decToHex(decimal,hexadecimal);
printf("Hexadecimal: %s\n", hexadecimalno);
char zeroes [8 - strlen(hexadecimalno)];
if(strlen(hexadecimalno) < 8){
    for(i = 0; i < (8-strlen(hexadecimalno)); i++){
        zeroes[i]='0';
    }
}
printf("zeroes: %s\n",zeroes);
strcat(zeroes,hexadecimalno);
printf("zeroes: %s\n",zeroes);

result

在 C 中,字符串(如您所知,是字符数组)没有任何特殊的元数据来告诉您它们的长度。相反,约定是字符串在 char 值为 0 的第一个字符处停止。这叫做"null-termination"。您的代码初始化 zeroes 的方式不会在数组末尾放置任何空字符。 (不要将您输入的 '0' 字符与 NUL 字符混淆——它们具有 char48,而不是 0。)

所有字符串操作函数都采用此约定,因此当您调用 strcat 时,它会寻找 0 字符来决定开始添加十六进制值的点。

C也不会自动为你分配内存。它假定您确切地知道自己在做什么。因此,您的代码使用 C99 功能来动态分配一个数组 zeroes,该数组的元素数量恰好与您需要的 '0' 个字符相同。您 没有 为终止 NUL 字符分配一个额外的字节,并且 strcat 还将假设您已经为 [= 的内容分配了 space 22=],你没有。在 C 中,这不会触发边界检查错误。它只是覆盖你实际上不应该覆盖的内存。因此,您需要非常小心,确保 分配足够的内存,并且只写入实际分配的内存。

在这种情况下,您希望 hexadecimalno 的长度始终为 8 位,并在其左侧填充零。这意味着您需要一个包含 8 个 char 值的数组,外加一个用于 NUL 终止符。所以,zeroes 需要是 char[9].

在为正确数量的零设置 zeroes[i] = '0' 的循环之后,您需要将 next 元素设置为 char0.你是零填充的事实混淆了事情,但再次记住 '0'0 是两个不同的东西。

前提是你分配了足够的 space(至少 9 个字符,假设 hexadecimalno 永远不会超过 8 个字符),然后你在将零放入数组时 null 终止数组对于填充,您应该会得到预期的结果。