以下是官方D书中的一个例子:
import std.stdio;
import std.string;
void main()
{
File file = File("student_records", "w");
file.writeln("Name : ", "Zafer");
file.writeln("Number: ", 123);
file.writeln("Class : ", "1A");
file.close();
File file1 = File("student_records", "r");
while (!file1.eof()) {
string line = (chomp(file1.readln()));
writeln("read line -> |", line);
}
}
如果你运行它,你会得到:
ldc2 -run file.d
read line -> |Name : Zafer
read line -> |Number: 123
read line -> |Class : 1A
read line -> |
注意打印出一个空行。现在,如果我将第三个writeln改为write,
import std.stdio;
import std.string;
void main()
{
File file = File("student_records", "w");
file.writeln("Name : ", "Zafer");
file.writeln("Number: ", 123);
file.write("Class : ", "1A");
file.close();
File file1 = File("student_records", "r");
while (!file1.eof()) {
string line = (chomp(file1.readln()));
writeln("read line -> |", line);
}
}
然后不再打印最后一个空行:
ldc2 -run file.d
read line -> |Name : Zafer
read line -> |Number: 123
read line -> |Class : 1A
我想知道为什么这会产生影响:readln应该读到行的末尾,包括行终止符号,为什么当我们显然达到EOF时应该有一个额外的循环?
答案 0 :(得分:8)
我的猜测是readln读取并包括行终止符('\n'
)但不包括EOF。你的文件看起来像这样:
Name : Zafer\n <---- first readln
Number: 123\n <---- second readln
Class : 1A\n <---- third readln
EOF <---- fourth readln
在readln
的第三次调用之后,还有更多内容需要阅读,即使它只是EOF。对readln
的最后一次调用返回null,writeln
愉快地接受并且不打印任何内容(在字符串“read line - &gt; |”之后)。 docs on readln中给出的示例实际检查readln
是否返回null并使用它来终止。
// Reads $(D stdin) and writes it to $(D stdout).
import std.stdio;
void main()
{
string line;
while ((line = stdin.readln()) !is null)
write(line);
}
另一种选择是使用foreach
:
foreach(line ; file1.byLine) {
writeln("read line -> |", line.chomp);
}
以上和文档中的示例都避免打印该空行。
如上所述,在创建文件时用writeln
替换上一个write
也可以避免打印最后一个空行,因为只有一个\n
,所以第三次调用{ {1}}直接读到readln
而不会在最终EOF
停止。