【问题标题】:Replacing a Null Character with other character in C用C中的其他字符替换空字符
【发布时间】:2020-04-27 08:29:11
【问题描述】:

在这段代码中:

  int main()
{
    char arr[5]="knot";
    char *ptr, *ptr1;
    int i;
    ptr = &arr[1];
    ptr1 = ptr + 3;
    *ptr1 = 101;
    for(i=0 ; i<4 ; i++)
        printf("%c", *ptr++);

    return 0;
}

输出恰好是note

我理解的是行,ptr = &amp;arr[1]; 指向 ptr 到原始数组的第二个内存位置,ptr1 = ptr + 3; 指向 ptr1 到空字符('\0')存储在原始数组中的位置. 之后*ptr1 = 101; 将原始数组中的空字符('\0')替换为e。之后,我从 ptr 指向最多 4 个字符的位置打印。

我对代码的解释是这样的

我不明白的是,虽然我将空字符('\0')替换为其他字符,但为什么

puts(arr);

for(i=0 ; i<10 ; i++)
   printf("%c", arr[i]);

仍然打印note,而不是打印e 后的一些垃圾值。在第二个 for 循环语句中,我尝试打印超出其范围的数组,但它仍然打印 note

会不会是e 之后的内存位置只包含空格?将来打印这样的字符串/字符数组是否安全?

PS:我使用的是 gcc (tdm64-1) 5.1.0

【问题讨论】:

  • puts(arr)(删除空终止符后)和越界访问数组都会调用 未定义的行为 - 任何事情都可能在此时发生,包括看似正确的结果

标签: c arrays string gcc


【解决方案1】:

会不会是e 之后的内存位置只包含空格?

不完全是,而是值0,它充当空终止符。因此,处理字符串的函数以某种方式显示看似正确的行为。对于循环和访问单个元素的情况,尝试访问未分配给进程的内存位置(即不是有效的内存)是undefined behaviour

以后打印这样的字符串/字符数组安全吗?

绝对不是。你得到的结果超出了undefined behavior,既不保证也不可靠。

【讨论】:

  • C 中的字符串可以0 终止还是 Null('\0') 终止?非常感谢您解决了我的疑问。
  • @zeroSpook '\0' 的值是0
【解决方案2】:

您的实例可能恰好是这种情况。我通过以下方式复制了您的代码:

for(i=0 ; i<25 ; i++){
    printf("%c", *ptr++);
}

printf("\n--------\n");


for(i=0 ; i<25 ; i++){
    printf("%c", arr[i]);
}

printf("\n--------\n");

i=0;
while(arr[i] != '\0'){
    printf("%c",arr[i++]);
}
printf("|");

得到以下结果

最好不要使用您使用的 for 方法进行打印。它会给您带来不准确的结果,并可能导致安全问题,更不用说很有可能误算。

我个人认为最好坚持使用 puts 或 while(arr!='\0') 或者如果使用 for 循环将停止条件设置为 sizeof(arr)/sizeof(char)

【讨论】:

  • 是的,我也观察到,当我将 i
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-12
  • 1970-01-01
  • 1970-01-01
  • 2018-10-04
  • 2019-11-21
  • 1970-01-01
相关资源
最近更新 更多