2012-05-31 42 views
8

我從讀取一行像所有的文件中讀取:如何使掃描儀正確閱讀轉義字符?

Hello World!\nI've been trying to get this to work for a while now.\nFrustrating.\n 

我的掃描器讀取從文件並把它在一個字符串:

Scanner input = new Scanner(new File(fileName)); 
String str = input.nextLine(); 
System.out.print(str); 

現在,我想輸出然後是:

Hello World! 
I've been trying to get this work for a while now. 
Frustrating. 

但相反,我得到了與輸入完全相同的東西。也就是說,每個\ n都包含在輸出中,並且所有內容都在一行而不是單獨的行中。

我認爲Scanner能夠正確讀取轉義字符,但它將其複製到字符串中,就像是\\ n。

回答

3

如果\n寫的是你不能使用nextLine()文件,因爲沒有\n(行尾),但是有\\n(兩個字符)。

而是用分隔符嘗試:

Scanner sc = new Scanner(new File("/home/alain/Bureau/ttt.txt")); 
    sc.useDelimiter("\\\\n"); 
    while(sc.hasNext()){ 
     System.out.println(sc.next()); 
    } 

輸出:

的Hello World!

我一直試圖讓這個工作一段時間。

令人沮喪。

編輯:

如果要讀取的文件,並與實際EOL文本替換\n。您可以簡單地使用:

Scanner sc = new Scanner(new File("/home/alain/Bureau/ttt.txt")); 

//loop over real EOL 
while(sc.hasNextLine()){ 

    //Replace the `\n` in the line with real EOL. 
    System.out.println(sc.nextLine().replace("\\n", System.getProperty("line.separator"))); 
} 
4

不,Scanner不會爲你做到這一點。你必須自己做翻譯。

(請注意,如果你使用類似sc.useDelimiter("\\\\n")正如其他人建議你打破了普通next()方法的功能和預期nextLine()可能無法正常工作。)

這裏是我將如何解決這個問題的草圖:

變化

Scanner input = new Scanner(new FileReader(fileName)); 

Scanner input = new Scanner(new JavaEscapeReader(new FileReader(fileName))); 
          ^^^^^^^^^^^^^^^^^^^^^      ^

其中JavaEscapeReader將延長FilterReader這樣的:

class JavaEscapeReader extends FilterReader { 

    JavaEscapeReader(Reader in) { 
     super(in); 
    } 

    @Override 
    public int read() throws IOException { 
     int ch = super.read(); 
     switch (ch) { 
     case '\\': 
      switch (super.read()) { 
      case '\\': return '\\'; 
      case 'n': return '\n'; 
      case 't': return '\t'; 
      case 'f': return '\f'; 
      // ... 
      default: 
       throw new IOException("Invalid char sequence."); 
      } 
     default: 
      return ch; 
     } 
    } 

    @Override 
    public int read(char[] cbuf, int off, int len) throws IOException { 
     int i = 0, ch; 
     while (i < len && -1 != (ch = read())) 
      cbuf[i++] = (char) ch; 
     return i == 0 ? -1 : i; 
    } 
} 

給定的輸入文件與內容

Line1\nLine2 
Line3\nLine3 

程序

Scanner sc = new Scanner(new JavaEscapeReader(new FileReader("filename.txt"))); 
while (sc.hasNextLine()) 
    System.out.println(sc.nextLine()); 

打印

Line1 
Line2 
Line3 
Line4 

另一種選擇是使用StringEscapeUtils.unescapeJava和後處理的讀取字符串。

2

您可以使用Scanner.useDelimiter設置您自己的分隔符。在你的情況下,使用雙引號\\n

s.useDelimiter("\\\\n"); 

例子:

Scanner s = new Scanner("Hello World!\\nI've been trying to get this to " + 
         "work for a while now.\\nFrustrating.\\n"); 
s.useDelimiter("\\\\n"); 

System.out.println(s.next()); 
System.out.println(s.next()); 
System.out.println(s.next()); 

輸出:

Hello World! 
I've been trying to get this to work for a while now. 
Frustrating. 
+0

假設我需要輸入存儲在字符串中以便將來使用。 有沒有什麼辦法可以正確存儲轉義字符,直接進入System.out? – sangh

+1

@ user1427895看我的編輯。 –

+0

@ alain.janinm太棒了!這似乎已經做到了。謝謝! – sangh