• 7585阅读
  • 4回复

请问QT4.4.1中有没有直接判断文件编码的方法? [复制链接]

上一主题 下一主题
离线xypylove
 

只看楼主 正序阅读 楼主  发表于: 2008-09-12
— 本帖被 XChinux 执行加亮操作(2008-09-14) —
如题,现在程序要实现打开各种编码的文本文件,如UTF-8,UNICODE等,在知道其编码格式的情况下已可以实现打开支持,现在要做的是让程序自动判断文本编码,从而调用正确的方式打开文件,现在急需解决的是判断UTF-8编码的方法,恳请知道的朋友告知,万分感谢呀!
离线maidisula

只看该作者 4楼 发表于: 2012-08-09
如果utf8文件开始部分没有标示该怎样判断呢?
离线xypylove

只看该作者 3楼 发表于: 2008-09-16
最后没办法,自己先判断了文本开始的前3个字节,判断是否是UTF8编码的,具体实现如下(相关代码部分):

void MainWindow::loadFile(const QString &fileName)
{
    QFile file(fileName);
    if(!file.open(QFile::ReadOnly | QFile::Text))
    {
        QMessageBox::warning(this, tr("Application"),
                            tr("Cannot read file %1:\n%2.")
                            .arg(fileName)
                            .arg(file.errorString()));
        return;
    }

    QTextStream in(&file);


   
    QString str;
    str = in.readAll();

    QString strTemp = str;

    QByteArray ba = strTemp.toLocal8Bit();

    int i = ba.size();

    bool flag = isUtf8(ba);

    QApplication::setOverrideCursor(Qt::WaitCursor);


    if(flag)
            textEdit->append(QString::fromUtf8(str.toLocal8Bit().data()));
    else
            textEdit->append(str);
   
    QApplication::restoreOverrideCursor();

    setCurrentFile(fileName);
    statusBar()->showMessage("装载成功", 2000);
}
bool MainWindow::isUtf8(QByteArray ba)
{
    QByteArray temp;
    temp.resize(3);
    temp[0] = 0xEF;
    temp[1] = 0xBB;
    temp[2] = 0xBF;

    bool flag = false;

    int i = ba.length();
    if(i < 3)
    {
        if((ba[0] == temp[0])&&(ba[1] == temp[1]))
            flag = true;
    }
    else
        if((ba[0] == temp[0])&&(ba[1] == temp[1])&&(ba[2] == temp[2]))
            flag = true;

    return flag;
}
离线yj_yulin

只看该作者 2楼 发表于: 2008-09-14
打开文件,先读一段文字出来,把它传入函数,然后告诉你是不是UTF-8,读的文字越多越准确
离线xypylove

只看该作者 1楼 发表于: 2008-09-12
论坛里看到的两种方法:
不知道传进来的这个参数应该怎么设置,求解呀!谢谢各位大虾!要用这个判断一个文本文件的话,应该传什么参数进来呀,谢谢了!

/*!\class bool xxx::isUtf8(const char *str)
* \brief utf8编码编码判断函数
* \param 无
* \author qqqmal
* \version 无
* \exception 无
* \return 无
*/
bool xxx::isUtf8(const char *str)
{
    unsigned int len = strlen (str);
    unsigned int counter = 0;
    unsigned char head = 0x80;
    unsigned char tempStr;
    unsigned int gbNum = 0,utf8Num = 0;
    bool gb2 = FALSE;/*第二个字节是否为汉字 */
   
    for (int i=len-1; i>=0; i--) {
        tempStr = (unsigned char)str[ i];
        /*GB判断, gb范围:第一字节161~247,第二字节161~254 */
        if (!gb2 && (tempStr>161) && (tempStr<254)) {
              gb2 = TRUE;
        }
        else
        if (gb2 && (tempStr> 161) && (tempStr<247)) {
              gbNum++;
              gb2 = FALSE;       
        }
        else
        {
              gb2 = FALSE;   
        }
       
        /* utf8判断 */
        if ((tempStr&0xc0) == 0x80 ) {
              counter ++;
              head = head>>1;
              head |= 0x80;
        }
        else
        if (counter > 0) {
              if ((((head>>1)|0x80)&tempStr) == head) {
                  utf8Num++;
                  head = 0x80;
                  counter = 0;
            }
        } else {
              head = 0x80;
              counter = 0;
        }
    }

    if (gbNum*2 <= utf8Num*3) {
        return TRUE;
    } else {
        return FALSE;
    }
}

使用方法举例:
    if (isUtf8(text)) {       
        label->setText(QObject::trUtf8 (text));
    } else {
        label->setText(QObject::tr (text));
    }

    }



//try this one. it will yield more accurate result.

const bool BTStringMgr::isUtf8(const char *buf) {
int i, n;
register unsigned char c;
bool gotone = false;

#define F 0  /* character never appears in text */
#define T 1  /* character appears in plain ASCII text */
#define I 2  /* character appears in ISO-8859 text */
#define X 3  /* character appears in non-ISO extended ASCII (Mac, IBM PC) */

static const unsigned char text_chars[256] = {
    /*            BEL BS HT LF  FF CR  */
    F, F, F, F, F, F, F, T, T, T, T, F, T, T, F, F, /* 0x0X */
    /*                    ESC      */
    F, F, F, F, F, F, F, F, F, F, F, T, F, F, F, F, /* 0x1X */
    T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x2X */
    T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x3X */
    T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x4X */
    T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x5X */
    T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, /* 0x6X */
    T, T, T, T, T, T, T, T, T, T, T, T, T, T, T, F, /* 0x7X */
    /*        NEL                  */
    X, X, X, X, X, T, X, X, X, X, X, X, X, X, X, X, /* 0x8X */
    X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, /* 0x9X */
    I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xaX */
    I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xbX */
    I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xcX */
    I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xdX */
    I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, /* 0xeX */
    I, I, I, I, I, I, I, I, I, I, I, I, I, I, I, I  /* 0xfX */
};

/* *ulen = 0; */
for (i = 0; (c = buf[i ]); i++) {
  if ((c & 0x80) == 0) {    /* 0xxxxxxx is plain ASCII */
    /*
    * Even if the whole file is valid UTF-8 sequences,
    * still reject it if it uses weird control characters.
    */

    if (text_chars[c] != T)
    return false;

  } else if ((c & 0x40) == 0) { /* 10xxxxxx never 1st byte */
    return false;
  } else {                  /* 11xxxxxx begins UTF-8 */
    int following;

  if ((c & 0x20) == 0) {        /* 110xxxxx */
    following = 1;
  } else if ((c & 0x10) == 0) {    /* 1110xxxx */
    following = 2;
  } else if ((c & 0x08) == 0) {    /* 11110xxx */
    following = 3;
  } else if ((c & 0x04) == 0) {    /* 111110xx */
    following = 4;
  } else if ((c & 0x02) == 0) {    /* 1111110x */
    following = 5;
  } else
    return false;

    for (n = 0; n < following; n++) {
    i++;
    if (!(c = buf[i ]))
      goto done;

    if ((c & 0x80) == 0 || (c & 0x40))
      return false;
    }
    gotone = true;
  }
}
done:
return gotone;  /* don't claim it's UTF-8 if it's all 7-bit */
}

#undef F
#undef T
#undef I
#undef X
快速回复
限100 字节
 
上一个 下一个