【问题标题】:Almost the same code, but different output, why?几乎相同的代码,但输出不同,为什么?
【发布时间】:2013-02-05 13:23:50
【问题描述】:

我正在处理 UTF-8 编码的文本文件,但找不到合适的解决方案...

在我无法解决字符串问题后,我现在正在尝试 fgetc(),但它也不起作用。 这段代码:

$file = fopen("t1.txt","r+");
while (! feof ($file))
{
  $c= fgetc($file);
  echo $c;
  //echo "\t";
}
fclose($file);

工作正常,输出:abcd абвқ efg 但是如果我取消注释 //echo "\t",它不起作用,它会输出: � � � a b c d � � � � � � � � � e f g

为什么?如何解决?

【问题讨论】:

    标签: php utf-8 fgetc


    【解决方案1】:

    您正在一次读取文件 byte

    例如,字符 б 在 UTF-8 中编码为字节 0xD0 0xB1。制表符是0x09

    所以没有制表符,你先写0xD0,然后写0xB1,得到0xD0 0xB1,这是有效的UTF-8。

    使用制表符,您可以在每个字节之间写入0x09 - 使其成为:0xD0 0x09 0xB10xD0 后跟 0x09 不是 有效的 UTF-8,所以浏览器会渲染替换字符来处理它。

    你需要更加成熟;这应该工作:

    $file = fopen("t1.txt","r+");
    while (! feof ($file))
    {
      $c = fgetc($file);
      $val = ord($c);
    
      //UTF-8 Lead Byte
      if( $val & 0x80 ) {
        $continuationByteCount = 0;
        if( ($val & 0xF8) == 0xF0) $continuationByteCount = 3;
        else if( ($val & 0xF0) == 0xE0) $continuationByteCount = 2;
        else if( ($val & 0xE0) == 0xC0) $continuationByteCount = 1;
    
        echo $c;
    
        while( $continuationByteCount-- ) {
            echo fgetc($file);
        }
    
      }
      else { //Single-byte UTF-8 unit... I.E. ASCII
          echo $c;
      }
      echo "\t";
    }
    
    fclose($file);
    

    一次读取所有内容并拆分为每个项目为 1 个字符(1-4 个字节)的数组:

    $chars = preg_split( '//u', file_get_contents("t1.txt"), -1, PREG_SPLIT_NO_EMPTY );
    
    foreach( $chars as $char ) {
        echo $char;
        echo "\t";
    }
    

    【讨论】:

    • 谢谢,这解决了这种情况,但无论如何我可以一次将文件的内容作为 UTF-8 获取,这样我就不需要处理 0xF8 或其他什么了,因为有这个文件有很多事情要做。或者无论如何我怎样才能正确地将文件的内容转换为字符串并通过索引访问它?
    • @hurremdev 查看替代解决方案
    【解决方案2】:

    我认为这可能是浏览器的编码识别问题。你可以试试

    <?php
    header('Content-type: text/html; charset=utf-8');
    ?>
    

    或者设置元标记

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    

    【讨论】:

      猜你喜欢
      • 2017-03-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-21
      • 2019-10-07
      • 2013-02-26
      • 2017-03-16
      相关资源
      最近更新 更多