0

我正在编写我自己的一种语言,称为 SPL。它有一个 Input 命令,它从ISplRuntime.Input属性中读取输入(它是 a TextReader)。所有其他命令都在这个界面上运行,因为这样我可以只用一个库编写不同的应用程序!

然后我编写了另一个控制台应用程序来测试我的语言。这是我的ISplRuntime. 关注Inputand 构造函数:

public class MyRuntime : ISplRuntime {
    protected TextReader reader;
    protected bool stopped;

    public object Current {
        get;
        set;
    }

    public virtual TextReader Input {
        get {
            return reader;
        }
    }

    public object[] Memory {
        get;
        protected set;
    }

    public TextWriter Output {
        get {
            return Console.Out;
        }
    }

    public bool Stopped {
        get {
            return stopped;
        }

        set {
            stopped = value;
            if (value) {
                Console.WriteLine ();
                Console.WriteLine ("Program has finished");
            }
        }
    }

    public void ShowErrorMessage (string error) {
        Console.WriteLine (error);
    }

    public MyRuntime () {
        string s = Console.ReadLine ();
        reader = new StringReader (s);
        stopped = false;
        Memory = new object[20];
    }
}

构建运行时时,它会要求输入。并使用该输入创建 aStringReader并将其返回到Input属性中。所以每次输入只会是一条线。

然后我在 SPL 中编写了一个输出输入的程序。这就是问题所在!当我输入 1 1 1 1 时,它会打印 1 1 1 并抛出FormatException. 这就是我阅读数字输入的方式:

private bool ReadFromInput (ISplRuntime runtime, out int i) {
    char stuffRead = (char)runtime.Input.Peek ();
    if (stuffRead == ' ') {
        i = 0;
        runtime.Input.Read ();
        return true;
    }

    if (char.IsNumber (stuffRead)) {
        string numberString = "";
        while (char.IsNumber (stuffRead)) {
            stuffRead = (char)runtime.Input.Read ();
            numberString += stuffRead;
        }

        i = Convert.ToInt32 (numberString); //This is where the exception occured! (Obviously, because there is no other methods that would throw it)
        return true;
    } else {
        i = 0;
        return false;
    }
}

参数runtime就是刚才看到的运行时。如果成功读取数字,则返回 true。而那个数字就是输出参数i

在 Visual Studio 中使用“Watch”窗口后,我发现数字字符串"1\uffff"是引发异常的时间。这就是它抛出它的原因!我知道(认为)那'\uffff'是行尾字符。但为什么它会出现在我的输入中?我知道(认为)按 Ctrl + Z 会结束行,但我没有!然后我检查runtime.Input了监视窗口。这是结果:

在此处输入图像描述

我看到有一个名为的字段_s,我认为这是我告诉它读取的字符串。看?_s甚至都不包含'\uffff',它怎么会读呢?

PS我已经知道解决方案了。我只需要while稍微改变一下循环就可以了。但我想知道为什么它读取行尾。

4

1 回答 1

4

这里没有谜团 -\uffff是由您的代码产生的。您所需要的只是阅读文档并了解您调用的方法返回什么。

TextReader.Peek 方法

返回值
类型:System.Int32
一个整数,表示要读取的下一个字符,如果没有更多可用字符或读取器不支持查找,则为-1 。

TextReader.Read 方法

返回值
类型:System.Int32
来自文本阅读器的下一个字符,如果没有更多可用字符,则返回-1 。

-1希望你能看到( 0xffffffff) 和之间的关系\uffff

于 2015-11-22T01:26:34.533 回答