2011-11-30 105 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