这是代码:

printf("   DEBUG:%s\n" ,array[7] );
printf("address of %s is %p  (again %d)\n",
    array[7],
    array[7],
    strcmp("N\\A", array[7]) );

printf("5DEBUG collection:%s\n" ,array[7] );

这是输出:

调试:不适用

是 0x7c0600(再次 -13)

5DEBUG 集合:N\A

如您所见,在第二个 printf - array[7] (需要指向 "N\A")中消失了。

我不知道这里发生了什么......

最佳答案

您正在 unix 上读取 Windows 格式的文件。 Windows 和 unix 使用不同的行终止符。 Unix 使用 0x0A,而 Windows 使用 0x0D 后跟 0x0A。

如果文件中有一行以 0x0D 0x0A 结尾,unix 会将 0x00A 视为行终止符,但将 0x0D 作为字符串的一部分包含在内。

您可以在返回 strcmp-13 中看到这一点。请注意,它不返回零,这意味着字符串不相等。其实差的是13,0x0D的十进制值,这证实了array[7]末尾有0x0D。

另一个证据是您看到的奇怪的打印行为。在 unix 上,打印 0x0D 会导致光标返回到同一行的第 0 列。因此,第二条打印指令以打印开始

address of N\A

然后遇到0x0D,它将光标移回第0列。因此,字符串的其余部分覆盖了输出,从而导致
 is 0x7c0600 (again -13)

如果您尝试在带有代码断点的调试器中调试程序,您会注意到 array[7] 末尾有一个 0x0D

添加了

这不是心理调试。这其实很简单。这是一步一步:
  • 当您注意到奇怪的行为时,您应该使用调试器查看 array[7] 中的字符串。如果你这样做了,你会看到尾随的 0x0D 并且问题会在 5 秒内解决。
  • 下一个重要线索是 strcmp 的结果不为零。这意味着 array[7] 中的字符串不等于 "N\\A" ,这是您应该使用调试器查看 array[7] 中的字符串以查看其实际内容的下一个重要线索。
  • 没有调试的好处,我观察到 array[7]"N\\A" 之间的区别一定是不容易看到的,因为第一行打印正常。此处的选项是控制字符或空格。
  • strcmp 报告了 13 的差异这一事实表明 array[7] 中的字符串末尾是 0x0D:"N\\A"\0 结尾(数值为零),13 的差异表明 array[7] 以 0x0D 结尾,因为 hex =0x 13 位十进制。
  • 如果您没有使用第 4 步中的逻辑,您可能会停下来思考,“哪些字符会打乱打印?”你在心理 list 上跑了下来。空格、制表符(导致打印多个空格)、回车(将光标返回到第 0 列)、换行符(前进到下一行)、换页(清除屏幕)和转义(引入控制台控制序列)。与证据匹配的是回车,其ASCII码是(惊喜)13。
  • 如果您没有使用步骤 4 或 5 中的逻辑,您可能已经研究过 Windows 上不存在问题的说法。 Windows 使用 0x0D 0x0A 作为其行终止符,而 unix 使用 0x0A。额外的 0x0D 是一个回车,它将光标返回到第 0 列,该列再次匹配证据。

  • 因此,有四种独立的方法可以得出相同的诊断结果。 (如果算上“查看调试器中的字符串”,则为 5。)由于他们都同意,因此得出了一个相当自信的结论。我的实际分析从第 5 步开始,然后使用其他步骤来确认诊断。

    关于c - 非常奇怪的行为 - printf & strcmp 仅在一行中忽略我的输入字符串,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/16600066/

    10-12 17:45