【问题标题】:C Why is an unrelated/undeclared variable influencing the output of another?C 为什么一个不相关/未声明的变量会影响另一个变量的输出?
【发布时间】:2017-04-29 04:08:08
【问题描述】:

当字符数组substring[#]设置为[64]时,文件输出一个附加字符。附加字符因每次编译而异。有时es?,有时esx等等。

如果我将 [64] 更改为任何其他数字(至少我尝试过的数字:65、256、1..),它会正确输出为 es

更奇怪的是,如果我将未使用/未声明的字符数组 char newString[64] 留在此文件中,即使是 64,它也会输出正确的子字符串 es

  1. 看似随意的 64 大小如何影响输出?
  2. 完全不相关的字符数组 (newString) 如何影响另一个字符数组的输出?

.

int main () {
    char string[64];    
    char newString[64];
    char substring[64];

    fgets(string,64,stdin); 
    strncpy(substring, string+1, 1);
    printf("%s\n", substring);

    return 0;
}

【问题讨论】:

  • 注意strncpy的正确使用;它不附加终止零。看起来好像您认为它会从另一个子字符串中“提取”一个子字符串。
  • 您的程序有未定义的行为。因此,您问题的整个前提都是错误的-要求对 UB 的行为进行解释是没有意义的。您的问题应该是 - 我的代码中的错误在哪里。答案可能在这里:strncpy(substring, string+1, 1)string+1 跳过整个字符串缓冲区并指向它后面的字节。而且您也只复制 1 个字节,然后尝试将其打印为字符串。
  • 你的意见是什么?
  • @kaylum: "string+1 跳过整个字符串缓冲区..." - 这不是真的。 string+1 指向 string[1],完全符合 OP 的意图。它不会跳过整个缓冲区。行为确实是未定义的,但出于完全不同的原因(参见 iharob 的回答)
  • 如果您希望得到明确定义的行为,初始化缓冲区通常是个好主意。因此,我会将您的变量声明更改为如下所示:char string[64] = {0};

标签: c substring strncpy


【解决方案1】:

问题是,strncpy() 不会复制 null 终止符,因为您要求它不要这样做。

同时使用strncpy() 是安全和危险的,因为它不会总是复制null 终止符,对于单个字节也使用它是没有意义的,而是这样做

substring[0] = string[1];
substring[1] = '\0';

它会起作用的。

您应该阅读手册页strncpy(3) 以正确理解我的意思,如果您每次都仔细阅读手册,您会在更短的时间内成为更好的程序员。

【讨论】:

  • 我建议测试字符串的长度是否至少为 2,以免在实际字符串结束后接管字符(这可能不是故意的)。例如if (strlen(string) >= 2) substring[0] = string[1] else substring[0] = '\0';
  • @StephanLechner 检查一下是一个很好的做法,我不会更改答案,因为评论就足够了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-02
  • 1970-01-01
  • 2013-12-04
  • 1970-01-01
  • 2014-02-07
相关资源
最近更新 更多