以下是官方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);
}
}
Run Code Online (Sandbox Code Playgroud)
如果你运行它,你会得到:
ldc2 -run file.d
read line -> |Name : Zafer
read line -> |Number: 123
read line -> |Class : 1A
read line -> |
Run Code Online (Sandbox Code Playgroud)
请注意,打印出一个空行.现在,如果我将第三个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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后不再打印最后一个空行:
ldc2 -run file.d
read line -> |Name : Zafer
read line -> |Number: 123
read line -> |Class : 1A
Run Code Online (Sandbox Code Playgroud)
我想知道为什么这会产生影响:readln应该读到行的末尾,包括行终止符号,为什么当我们明显达到EOF时应该有一个额外的循环?
我的猜测是readln读取并包括行终止符('\n')但不包括EOF.你的文件看起来像这样:
Name : Zafer\n <---- first readln
Number: 123\n <---- second readln
Class : 1A\n <---- third readln
EOF <---- fourth readln
Run Code Online (Sandbox Code Playgroud)
在第三次调用之后readln,还有更多要阅读,即使它只是EOF.这最后一次调用readln返回null,它很writeln乐意接受并且不打印任何内容(在字符串"read line - > |"之后).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);
}
Run Code Online (Sandbox Code Playgroud)
另一种选择是使用foreach:
foreach(line ; file1.byLine) {
writeln("read line -> |", line.chomp);
}
Run Code Online (Sandbox Code Playgroud)
以上和文档中的示例都避免打印该空行.
与上面的描述,免去您的最后一个writeln与write创建文件时,也避免了打印的最后一个空行有一个少\n,因此第三个呼叫readln直通到读EOF不停止在最后\n.