2011-11-30 102 views
16

如果我在CMD中輸入å,fgets停止等待更多輸入,並且循環運行,直到我按ctrl-c。如果我輸入「正常」字符,如a-z0-9!?(),則按預期工作。如何從CLI標準輸入讀取非ASCII字符

我使用UTF-8作爲字符集(chcp 65001)在Windows 7下運行CMD中的代碼,該文件保存爲UTF-8而不包含bom。我使用PHP 5.3.5(cli)。

<?php 

echo "ÅÄÖåäö work here.\n"; 

while(1) 
{ 
    echo '> '. fgets(STDIN); 
} 

?> 

如果我改變字符集來chcp 1252當我輸入å並打印「>一個」但是「ÅÄÖåäö在這裏工作」成爲「......一個個」-A¥Ã¤Ã循環不破¶在這裏工作!「。而且我知道我可以將文件更改爲ANSI,但是我不能使用像╠╦╗這樣的特殊字符。

那麼爲什麼fgets在輸入åäö後停止等待userinput?

我該如何解決這個問題?

編輯:

還發現了一個奇怪的錯誤。 echo "öäåÅÄÖåäö work here! Or?".chr(10); - >��äåÅÄÖåäö work here! Or? re! Or?。 如果echo中的第一個字符是å/ä/ö,它會打印奇怪的字符,並輸出結果與n - 1 char ..(n =字符串開頭的數字)。

例如:echo "åäö 1234" -> ??äö 123434echo åäöåäö 1234??äöåäö 1234 1234

EDIT2(解決):

問題是chcp 65001,現在我用chcp 437chcp 437)。 非常感謝Timothy Martens!

+0

關於這個問題的幾個問題:1)當你嘗試在PHP之外的CMD中鍵入和「å」時會發生什麼? 2)UTF-8''與Windows-1252''不一樣是合乎邏輯的,因此產生''。但是如果您嘗試將PHP文件轉換爲Windows-1252,會發生什麼情況? – Qqwy

+0

** 1)**åäö - >「命令不喜歡」,echoåäö - >åäö。所以它工作。兩者都使用'chcp 65001'(UTF-8)和'chcp 1252'。 ** 2)**我在cmd中使用UTF-8,並將其作爲PHP文件的字符集。如果我在PHP文件中使用windows-1252,則不會有任何更改。我認爲這個問題是在Windows/PHP中。當我使用'chcp 1252'時,它適用於ÅÄÖ(即使PHP文件是UTF-8),但後來我不能使用╠╦╗等。 – Sawny

+0

男人,多麼有趣的問題^^。你現在真的有我的注意力。我將嘗試一下自己,我會盡快告訴你。 – Qqwy

回答

5

可能的解決辦法:

echo '>'; 
$line = stream_get_line(STDIN, 999999, PHP_EOL); 

注: 我無法重現使用PHP的多個版本的錯誤。 使用下面的PHP版本5.3.8沒有給我任何問題

PHP 5.3(5.3.8) VC9 86非線程安全的(2011 - 8 - 23 12時26分18秒) Arcitechture是Win XP的SP3 32位

您可以嘗試升級PHP。

我下載了php-5.3.5-nts-Win32-VC6-x86,無法重現你的錯誤,對我來說工作正常。

編輯:另外我用西班牙語鍵盤輸入了字符。

EDIT2:

CMD命令:

chcp 437 

PHP代碼:

<?php 
$fp=fopen("php://stdin","r"); 
while(1){ 
    $str = fgets(STDIN); 
    echo mb_detect_encoding($str)."\n"; 
    echo '>'.stream_get_line($fp,999999,"\n")."\n"; 
} 
?> 

輸出:

test 
ASCII 
test 
>test 
öïü 

öïü 
>öïü 
+0

** 1)**'stream_get_line'不起作用。 ** 2)**我現在下載了'VC9 x86非線程安全(2011-Aug-23 12:26:18)',但沒有奏效。你在CMD和你的代碼中使用什麼字符集?順便說一句,我運行W7 64位。 – Sawny

+0

@Timoth Martens在windows cmd上不會是'stream_get_line(STDIN,999999,PHP_EOL);'?無論如何我都會更新你的答案。無論如何。似乎是目前爲止最好的解決方案。 –

+1

** NOTE **:我剛剛在我的Mac上使用PHP 5.3.6和PHP 5.2.14進行了測試,並且都能正常工作。 –

2

我認爲這是因爲PHP 5.3不能正確支持多字節c haracters。

這些字符:ÅÄÖåäö

是二進制:c3 85 c3 84 c3 96 c3 a5 c3 a4 c3 b6(無BOM在beggining)

援引PHP String

字符串是一系列字符,其中一個字符是相同的一個字節。這意味着PHP僅支持256個字符的集合,因此不提供本地Unicode支持。查看字符串類型的詳細信息。

通常不影響最終的結果,因爲瀏覽器/閱讀器理解多字節字符,但對於CMD和STDIN緩衝器是ÅÄÖåäö(12個字符/字節字符數組)。

只有MB functions處理多字節字符串的基本操作。

+0

是的我知道的MB功能,但他們沒有任何閱讀資源功能:( – Sawny