几乎相同的代码,但不同的输出,为什么?

时间:2013-02-05 13:23:51

标签: php utf-8 fgetc

我正在使用UTF-8编码的文本文件,无法找到合适的解决方案......

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

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

工作正常,并输出:abcdабвқff 但如果我取消注释// echo“\ t”,它就不起作用,它会输出: a b c d f f f f g

为什么呢?如何解决?

2 个答案:

答案 0 :(得分:3)

您正在一次读取文件 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";
}

答案 1 :(得分:0)

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

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

或设置元标记

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