【发布时间】:2020-08-17 05:27:07
【问题描述】:
我正在开发一些在 Windows 上运行的用 Delphi 7 编写的遗留软件。我已将问题缩小到以下程序:
var f: text;
begin
assign(f, 'a.txt');
rewrite(f);
writeln(f, 'before' + chr(14) + 'after');
close(f);
assign(f, 'a.txt');
append(f);
close(f);
end.
我希望它创建包含"before#14after#13#10" 的a.txt 文件,然后不附加任何内容。但是,在 Windows 上运行该程序后,我在 a.txt 中看到了 before,就像 Delphi 的 append 截断文件一样。如果我不重新打开文件,它会按预期显示before#14after#13#10。
如果我在重新打开的文件中写了一些东西 (FooBar),它会被附加,但好像文件已经被截断:beforeFooBar。
0 到 32 之间的任何其他字符都不会出现这种效果,即使是 26(代表 EOF)也是如此。
这是 Delphi 中的错误还是定义明确的行为? chr(14) 有什么特别之处?
【问题讨论】:
-
它在 Delphi 4 (Windows 95) 和 Delphi 10.3 (Windows 7) 中都能正常工作。我目前无权访问任何 Delphi 7 安装。 (顺便说一句,ASCII 14 是 SHIFT OUT。)
-
非常有趣,感谢您查看其他版本!我会继续在本地挖掘。
-
我可以确认:使用 Delphi 7 并调试文件按预期写入(大小 14 字节),但是当调用
append()时,文件的长度被截断为 6 字节。我只能假设 ASCII 14 并不真正被视为“文本”,而函数试图找到行尾。将此视为未定义的行为。 -
好吧,胡乱猜测:有人在 Delphi 7 的源代码中写了
eof,假设它是一个正确的常量,但它是 turns out to be 14 O_O -
@yep 的发现。如果源不可用,则此行
CMP byte ptr [ESI].TTextRec.Buffer[EAX],eof应为CMP byte ptr [ESI].TTextRec.Buffer[EAX],cEOF。