您正在 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
不为零。这意味着 in 中的字符串array[7]
不等于"N\\A"
,这是您应该使用调试器查看字符串array[7]
以查看其实际内容的下一个重要线索。
array[7]
没有调试的好处,我观察到和之间的区别"N\\A"
必须在一些不容易看到的东西上,因为第一行打印没问题。这里的选项是控制字符或空格。
strcmp
报告差异的事实13
表明字符串 inarray[7]
末尾有一个 0x0D:"N\\A"
以 a \0
(数值零)结尾,差异 13 表明array[7]
以 0x0D 结尾,因为 0x0d 十六进制 = 13 十进制。
- 如果您不使用步骤 4 中的逻辑,您可能会停下来思考“哪些字符会弄乱打印?” 你在心理清单上跑了。空格、制表符(导致打印多个空格)、回车(将光标返回到第 0 列)、换行(前进到下一行)、换页(清除屏幕)和转义(引入控制台控制序列)。与证据相符的是回车,其ASCII码为(惊喜)13。
- 如果您没有使用步骤 4 或 5 中的逻辑,您可能已经研究过 Windows 上不存在该问题的陈述。Windows 使用 0x0D 0x0A 作为其行终止符,而 unix 使用 0x0A。额外的 0x0D 是一个回车符,它将光标返回到第 0 列,这再次与证据匹配。
因此,有四种独立的方法可以得出相同的诊断。(如果算上“查看调试器中的字符串”,则为五个。)由于他们都同意,因此得出了一个相当有把握的结论。我的实际分析从步骤 5 开始,然后使用其他步骤来确认诊断。