在 D readf 中输入了错误的类型后如何读取输入?

How can I read input after the wrong type has been entered in D readf?

我想知道在程序读取了不合适的值后如何继续在 D 中使用标准输入。 (例如,期待 int 时的字母) 我写这个是为了测试它:

import std.stdio;


void main()
{
    int a;
    for(;;){
        try{
            stdin.readf(" %s", a);
            break;
        }catch(Exception e){
            writeln(e);
            writeln("Please enter a number.");
        }
    }
    writeln(a);
}

输入不正确的值(例如'b')后,程序会不确定地打印出消息。我还检查了表明它试图再次读取相同字符的异常,所以我做了一个这样的版本:

import std.stdio;


void main()
{
    int a;
    for(;;){
        try{
            stdin.readf(" %s", a);
            break;
        }catch(Exception e){
            writeln(e);
            writeln("Please enter a number.");
            char c;
            readf("%c", c);
        }
    }
    writeln(a);
}

尝试读取 a 而不是 c 时仍然抛出异常。我也尝试使用 stdin.clearerr(),但没有效果。有谁知道如何解决这个问题?谢谢

我的建议:不要使用 readf。太糟糕了。每个人都首先使用它,因为它在 stdlib 中(自 1979 年以来一直如此,哈哈,scanf 有……而且我认为 scanf 比 readf 更好!但我离题了),几乎每个人都遇到了麻烦。当它正确时,它对格式和空格消耗非常挑剔,而当它出错时,它会给出糟糕的错误消息并使输入流处于不确定状态。而且,最重要的是,它在实际读取的数据类型方面仍然非常有限,而且对用户非常不友好,甚至不允许在大多数系统上进行退格等操作!

readf 稍微好一点的是使用 readln 然后 stripto!int 一旦你检查了行并给出了错误。像这样:

import std.stdio;
import std.string; // for strip, cuts off whitespace
import std.algorithm.searching; // for all
import std.ascii; // for isAscii
import std.conv; // for to, does string to other type conversions

int readInt() {
        for(;;) {
                string line = stdin.readln();
                line = line.strip();
                if(all!isDigit(line))
                        return to!int(line);
                else
                        writeln("Please enter a number");
        }
        assert(0);
}


void main()
{
    int a = readInt();
    writeln(a);
}

我知道有很多进口垃圾邮件(还有一堆单独的琐碎功能),readln 对最终用户来说仍然很糟糕,但是这个小功能对您的用户和自己而不是尝试使用 readf。它将始终如一地 一次消耗一行并给出一个很好的信息。此外,相同的模式可以扩展到您需要的任何其他类型的验证,并且可以将对 readln 的调用替换为对更用户友好的函数的调用,该函数允许稍后编辑和历史记录以及其他内容,如果您决定沿着那条路走下去。


如果您无论如何都必须使用 readf,那么在 catch 块中使事情恢复正常的最简单方法仍然是调用 readln 并丢弃其结果。因此,它只是跳过包含错误的整行,让您的用户重新开始。如果他们正在做“1 2”并且希望一次读取两个整数,那也会下降......但是,嗯,我宁愿重新开始它们,也不愿尝试在中途选择错误的行。