Java - 我的代码中的一个额外字符?

时间:2015-04-26 22:47:34

标签: java char console-application newline scanning

我正在使用3个类:Character类,Scanner类和Test类。

这是Character类:

public class Character {
    private char cargo = '\u0007'; 
    private String sourceText = ""; 
    private int sourceIndex = 0; 
    private int lineIndex = 0;
    private int columnIndex = 0;
    public Character(String sourceText, char cargo, int sourceIndex, int lineIndex, int columnIndex) {
        this.sourceText = sourceText;
        this.cargo = cargo;
        this.sourceIndex = sourceIndex;
        this.lineIndex = lineIndex;
        this.columnIndex = columnIndex;
    }
    /*****************************************************************************************/
    /* Returns the String representation of the Character object                      */
    /*****************************************************************************************/
    @Override
    public String toString() {
        switch (cargo) {
            case ' ': return String.format("%6d %-6d " + "    blank", lineIndex, columnIndex);
            case '\t': return String.format("%6d %-6d " + "    tab", lineIndex, columnIndex);
            case '\n': return String.format("%6d %-6d " + "    newline", lineIndex, columnIndex);
            default: return String.format("%6d %-6d " + cargo, lineIndex, columnIndex);
        }
    }
}

这是我的扫描仪课程:

public class Scanner {
    private String sourceText = ""; 
    private int sourceIndex = -1; 
    private int lineIndex = 0;
    private int columnIndex = -1;
    private int lastIndex = 0;
    /*****************************************************************************************/
    /* Assign proper values                                                                  */
    /*****************************************************************************************/ 
    public Scanner(String sourceText) {
        this.sourceText = sourceText;
        lastIndex = sourceText.length() - 1;
    }
    /*****************************************************************************************/
    /* Returns the next character in the source text                                         */
    /*****************************************************************************************/   
    public Character getNextCharacter() {
        if (sourceIndex > 0 && sourceText.charAt(sourceIndex - 1) == '\n') {
            ++lineIndex;
            columnIndex = -1;
        }
        ++sourceIndex;
        ++columnIndex;
        char currentChar = sourceText.charAt(sourceIndex);
        Character objCharacter = new Character(sourceText, currentChar, sourceIndex, lineIndex, columnIndex);
        return objCharacter;
    }
}

这是Test类的主要方法:

public static void main(String[] args) {
    String sourceText = "";
    String filePath = "D:\\Somepath\\SampleCode.dat";
    try { sourceText = readFile(filePath, StandardCharsets.UTF_8); }
    catch (IOException io) { System.out.println(io.toString()); }
    LexicalAnalyzer.Scanner sca = new LexicalAnalyzer.Scanner(sourceText);
    LexicalAnalyzer.Character cha;
    int i =0;
    while(i < sourceText.length()) {
        cha = sca.getNextCharacter();
        System.out.println(cha.toString());
        i++;
    }
}

基本上,我要做的是在源文件中打印每个字符(包括空格,制表符和换行符),以及其他字符详细信息,如行号和列号。另外,请在Character类的toString()方法中注意我的switch和case语句。

比方说,我的文件包含文字:

This is line #1. 
This is line #2.

从我的代码中,我期待得到:

 0 0      T
 0 1      h
 0 2      i
 0 3      s
 0 4          blank
 0 5      i
 0 6      s
 0 7          blank
 0 8      l
 0 9      i
 0 10     n
 0 11     e
 0 12         blank
 0 13     #
 0 14     1
 0 15     .
 0 16         newline
 1 0      T
 1 1      h
 1 1      i
 1 2      s
 1 3          blank
 1 4      i
 1 5      s
 1 6          blank
 1 7      l
 1 8      i
 1 9      n
 1 10     e
 1 11         blank
 1 12     #
 1 13     2
 1 14     .

但是,我得到了:

 0 0      T
 0 1      h
 0 2      i
 0 3      s
 0 4          blank
 0 5      i
 0 6      s
 0 7          blank
 0 8      l
 0 9      i
 0 10     n
 0 11     e
 0 12         blank
 0 13     #
 0 14     1
 0 15     .
 0 16     
 0 17         newline
 0 18     T
 1 0      h
 1 1      i
 1 2      s
 1 3          blank
 1 4      i
 1 5      s
 1 6          blank
 1 7      l
 1 8      i
 1 9      n
 1 10     e
 1 11         blank
 1 12     #
 1 13     2
 1 14     .

注意当有换行符时它会打印什么。空格和制表符可以正常工作。我得到了我想要的东西,但不是换新品。顺便说一下,这只是一个Java代码:http://parsingintro.sourceforge.net/#contents_item_4.2

请不要攻击我。我一直试图找出背后的原因数小时。

注意

使用%nString.format中的System.getProperty("line.separator");也可能有所帮助。请检查此链接:How do I get a platform-dependent new line character?

2 个答案:

答案 0 :(得分:4)

您正在Windows系统上运行。

代码不会以\r\n的形式处理换行符,而只是\n

我能够通过这种变化产生有意义的输出。将此案例添加到交换机:

case '\r': return String.format("%6d %-6d " + "    winNewline", lineIndex, columnIndex);

结果输出:

 0 0      T
 0 1      h
 0 2      i
 0 3      s
 0 4          blank
 0 5      i
 0 6      s
 0 7          blank
 0 8      l
 0 9      i
 0 10     n
 0 11     e
 0 12         blank
 0 13     #
 0 14     1
 0 15     .
 0 16         blank
 0 17         winNewline
 0 18         newline
 0 19     T
 1 0      h
 1 1      i
 1 2      s
 1 3          blank
 1 4      i
 1 5      s
 1 6          blank
 1 7      l
 1 8      i
 1 9      n
 1 10     e
 1 11         blank
 1 12     #
 1 13     2
 1 14     .

Process finished with exit code 0

答案 1 :(得分:3)

通过查看输出很难说,但是尝试调试它可以尝试修改字符类中的默认case语句,以便使用

打印char的ascii代码
default: return String.format("%6d %-6d " + Integer.valueOf(cargo), lineIndex, columnIndex);

这将显示您获得的额外字符的ascii代码是什么。获得代码后,请检查它在哪个字符:http://www.asciitable.com/

我的猜测是,你得到的额外字符是&#39; \ r&#39; (不同类型的&#39; \ n&#39; char)。

希望这有帮助!