2010-08-04 80 views
3
String messageFile = ... // Assume messageFile SHOULD have the string "MESSAGE" 
System.out.println("The messageFile is: " + messageFile + "!!"); 

通常情況下,人們所期望的上述命令的輸出:的bizzare的System.out.println()在Java程序

The messageFile is: MESSAGE!!!! 

不過,我收到此相反:

!!e messageFile is: MESSAGE 

看看上面的說法,「!!」點似乎圍繞着消息。我的理論是:

String messageFile = ... 

包含比我假設的「MESSAGE」更多的字符。因此,它將下一個輸入(在本例中爲「!!」)包裝到System.out.println()消息的前面。

是什麼字符造成這種情況?

額外的信息:

順便說一句,messageFile正在傳遞一個命令行參數的Java類,myClassA初始化。 myClassA的構造函數使用super()將messageFile參數傳遞給myClassB。 myClassB將messageFile傳遞給函數()。

+0

是否有可能不止一個線程同時寫入System.out?我有一種感覺,System.out中使用的PrintStreams不是線程安全的。 – 2010-08-04 16:58:35

+0

@matt打印或println的單個調用是作爲一個線程安全的操作發生的,但是如果System.out和System.err都指向相同的地方(例如控制檯),它們將會競爭,並且可能會看起來很「混合」輸出。 – 2010-08-04 18:16:42

回答

16

我猜你在messageFile變量內沒有伴隨行換行符(\n)有一個流浪回車(\r)。

編輯 - 這個測試預期:

class Println { 
     public static void main(String[] args) { 
       System.out.println("xxxx this \rTEST"); 
     } 
} 

輸出:

TEST this 
+0

+1正確的錢。 – 2010-08-04 17:22:45

+0

這可以說是消息中的消隱功能的一個問題。這可能不適當地處理IO格式。 – 2010-08-04 18:51:41

+0

也許在某些地方有人不使用標準系統屬性'line.separator':依賴於平臺的行分隔符(例如,UNIX上的「\ n」,Windows上的「\ r \ n」) 也許應用程序是在* NIX上開發的,但現在在某些Windows上使用,硬編碼\ n而不是使用line.separator屬性。所以有一些\ r剩餘的... – 2010-08-04 19:03:42

2

您的消息變量可能在末尾包含'\ r'(回車符)或'\ n'(換行符)字符。這可能會導致光標在打印感嘆號之前返回到第一列。

+0

-1錯誤。它必須是一個回車符(它可以返回到行的開頭)並且不能是換行符(它會下降到下一行)。當這些是兩個單獨的行爲時,這些是對打字機日子的倒退。當您將紙卷推回到右側時,回車時,您可以再次從第一列開始。換行時,當你推入一個將紙張送入一行的小槓桿時。在我使用過的每一臺打字機上,這些設計都是在同一時間進行的。 – 2010-08-04 17:21:51

+0

我完全意識到這一點。但是如果沒有關於海報正在使用的終端的知識,總是有可能它是一個折線提要。檢查兩者都沒有錯。 – relet 2010-08-04 20:14:55

1

爲了調試,你應該通過codePointAt打印messageFile每個字符的代碼點。 因此,您完全可以看到messageFile的內容。

0

替換換行符文件中的所有回車,然後用單換行符替換所有雙新行:

messageFile.replace('\r', '\n').replace("\n\n", "\n) 

回車應被禁止:d