`
f002489
  • 浏览: 271924 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

UTF8 和 GBK混合的文本识别转换.....

    博客分类:
  • C
 
阅读更多
http://bbs.chinaunix.net/thread-971041-1-1.html



#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <iconv.h>
#include <stdint.h>
#include <errno.h>

static int charconv(char *from, char *to,
        const char *input, int inlen, char **output, int *outlen)
{
        char *inbuf;
        char *outbuf;
        size_t inleft;
        size_t outleft;
        iconv_t cd;
        size_t result;

        cd = iconv_open(to, from);
        if (cd == (iconv_t) (-1)) {
                *outlen = -1;
                *output = NULL;
                return -1;
        }

        if (inlen == 0)
                inlen = strlen(input);
        *outlen = 4 * inlen;

        inbuf = (char *)input;
        outbuf = (char *) malloc(*outlen);

        inleft = inlen;
        outleft = *outlen;

        *output = outbuf;

#if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 2)
        result = iconv(cd, &inbuf, &inleft, &outbuf, &outleft);
#else
        result =
                iconv(cd, (const char **) &inbuf, &inleft, &outbuf, &outleft);
#endif

        iconv_close(cd);

        *outlen = *outlen - outleft;
        (*output)[*outlen] = 0;
        return inlen - inleft;
}

int isutf8(char *s, size_t ns)
{
        uint8_t x = 0, i = 0, j = 0, nbytes = 0, n = 0;

        for(i = 1; i < 7; i++)
        {
                x = (uint8_t)(255 << i);
                if(((uint8_t)*s & x) == x)
                {
                        n = nbytes = (8 - i);
                        for(j = 0; (j < nbytes && j < ns); j++)
                        {
                                if((uint8_t)s[j] <= 0x80 && (uint8_t)s[j] >= 0xc0)break;
                                else n--;
                        }
                        if(n == 0) return nbytes;
                }
        }
        return 0;
}

int isgbk(char *s, size_t ns)
{
        if(ns > 2 && (uint8_t)*s >= 0x81 && (uint8_t)*s <= 0xfe
                && (
                        ((uint8_t)*(s+1) >= 0x80 && (uint8_t)*(s+1) <= 0x7e)
                        || ((uint8_t)*(s+1) >= 0xa1 && (uint8_t)*(s+1) <= 0xfe)
                    )
          )
        {
                return 1;
        }
        return 0;
}

void convert(char *src, size_t nsrc, char **dst, int *ndst,
        const char *codefrom, const char *codeto)
{
        char *s = src, *d = (*dst), *end = (src + nsrc), *p = NULL;
        iconv_t handler, cd;
        size_t n = 0, ns = nsrc, nd = (*ndst), result = 0;
        size_t x = 0, nbytes = 0, nbuf = 16;
        char buf[nbuf];

        handler = iconv_open(codeto, codefrom);
        while(ns > 0)
        {
                n = ns;
                if((nbytes = isutf8(s, ns)) > 0)
                {
                        memcpy(d, s, nbytes);
                        s += nbytes;
                        d += nbytes;
                        ns -= nbytes;
                        nd -= nbytes;
                        //fprintf(stdout, "utf8:%d\n", ns);
                        //fprintf(stdout, "utf8:%d:%s\n", nbytes, (d - nbytes));
                }
                else if(isgbk(s, ns))
                {
                        memset(buf, 0, nbuf);
                        memcpy(buf, s, 2);
                        x = 2;
                        p = buf;
                        result = iconv(handler, &p, &x, &d, &nd);
                        ns -= 2;
                        s  += 2;
                        //fprintf(stdout, "gbk:%d\n", ns);
                }
                else
                {
                        *d++ = *s++;
                        ns--;
                        nd--;
                }
                if(ns == n) break;
        }
        //fprintf(stdout, "%s\n", *dst);
        iconv_close(handler);
}

#ifdef _DEBUG_UTF8_FILE
int main(int argc, char **argv)
{
        char *file = NULL;
        char *s = NULL, *inbuffer = NULL, *outbuffer = NULL;
        struct stat st;
        int i = 0, n = 0;
        FILE *fp = NULL;
        size_t nout;

        if(argc < 2)
        {
                fprintf(stderr, "Usage:%s file ...\n", argv[0]);
                _exit(-1);
        }

        for(i = 1; i <= argc; i++)
        {
                if((fp = fopen(argv[i], "r")))
                {
                        if(stat(argv[i], &st) == 0 && st.st_size > 0)
                        {
                                s = inbuffer  = (char *)calloc(1, (st.st_size + 1));
                                outbuffer = (char *)calloc(1, (st.st_size * 4 + 1));
                                nout = st.st_size * 4;
                                while((n = fread(s, 1, st.st_size, fp)) > 0)
                                {
                                        s += n;
                                }
                                if(( n = (s - inbuffer)) > 0)
                                {
                                        convert(inbuffer, n,
                                                        &outbuffer, &nout,
                                                        "gbk", "utf8");
                                        fprintf(stdout, "%s\n", outbuffer);
                                }
                                else
                                {
                                        fprintf(stderr, "read %s %d bytes failed, %s\n",
                                                argv[i], n, strerror(errno));
                                }
                                free(inbuffer);
                                free(outbuffer);
                        }
                        fclose(fp);
                }
        }
}
#endif

#ifdef _DEBUG_UTF8_STRING
int main(int argc, char **argv)
{
        int i = 0, n = 0;
        if(argc < 2)
        {
                fprintf(stderr, "Usage:%s string ...\n", argv[0]);
                _exit(-1);
        }

        for(i = 1; i < argc; i++)
        {
                if((n = isutf8(argv[i], strlen(argv[i]))) > 0)
                {
                        fprintf(stdout, "\"%s\" is %d bytes UTF8 charset\n", argv[i], n);
                }
                else if(isgbk(argv[i], strlen(argv[i])))
                {
                        fprintf(stdout, "\"%s\" is GBK charset\n", argv[i]);
                }
                else
                {
                        fprintf(stdout, "\"%s\" is unknown charset\n", argv[i]);
                }
        }
}
#endif
分享到:
评论
1 楼 f002489 2013-06-21  
ICU ,ICONV ,, http://bbs.csdn.net/topics/360181231

相关推荐

    GBK 与 UTF-8 间编码转换

    相反,从UTF-8到GBK的转换则需要识别出UTF-8编码的字节序列,找到对应的Unicode码点,再查找这个码点在GBK编码中的对应双字节序列。 在进行编码转换时,需要注意以下几点: 1. 检查原始文件的编码格式,避免乱码...

    GBK和UTF-8 互转.zip

    在编程中,GBK和UTF-8之间的转换通常涉及到以下几个关键知识点: 1. 字符编码识别:在进行转换之前,首先需要确定原始数据的编码类型,否则可能导致乱码问题。可以使用诸如`chardet`这样的库来自动检测文件或字符串...

    GBK源码转UTF8格式(QT源码)

    1. **使用文本编辑器**:首先,可以使用支持编码转换的文本编辑器,如Notepad++,打开GBK编码的源码文件,然后选择“编码”菜单,将其转换为UTF-8无BOM格式。 2. **QT代码实现**:如果你需要在QT项目中处理编码转换...

    易语言源码中英混合文本逐字分割例程.7z

    在实际应用中,为了提高效率和兼容性,还可能涉及编码转换,如GBK到UTF-8的转换,以便正确处理各种编码格式的文本。此外,考虑到易语言的跨平台特性,此例程可能还适用于不同的操作系统环境。 总结来说,“易语言...

    网页编码模板UTF/GBK转码工具 支持文件夹转换

    "网页编码模板UTF/GBK转码工具 支持文件夹转换"是一个专门针对网页编码转换的实用软件,它允许用户批量处理UTF和GBK两种编码格式之间的转换,尤其对处理大量网页文件或文件夹时非常方便。 首先,我们需要理解UTF和...

    易语言源码中英混合文本逐字分割例程.rar

    在处理中文和英文混合的文本时,由于中文字符通常由多个字节组成(如UTF-8编码下,一个中文字符通常占用3个字节),而英文字符通常为单字节,因此在进行逐字分割时需要特别注意字符编码的问题。这个例程可能采用了...

    Python-convert2utf将目录下的全部源文件转成UTF8编码

    标题"Python-convert2utf将目录下的全部源文件转成UTF8编码"指的是使用Python编写的一个脚本或工具,该工具能够遍历指定目录,检测并转换其中的GB、GBK以及其他非UTF-8编码的文本文件和源代码文件,统一转换为UTF-8...

    GBK转换Unicode 实用

    在实际应用中,GBK到Unicode的转换可能遇到的问题包括编码识别错误、乱码、以及处理混合编码的文件等。因此,在进行转换时,需要确保准确识别源文件的编码,并选择合适的转换方法。例如,如果文件中同时包含ASCII、...

    utf8.rar_UTF8

    - 空间效率:对于英语等主要使用ASCII字符的语言,UTF-8占用的空间与ASCII相同,而对于其他语言,如中文,虽然每个字符可能需要3或4个字节,但相比双字节的GBK编码,UTF-8在处理混合文本时能节省空间。 - 简化处理...

    VB数字中文识别软件.rar

    3. 中文字符集与编码:在识别中文时,需要处理GB2312、GBK、UTF-8等不同的中文编码方式。VB中的字符串操作函数,如`Chr()`和` Asc()`,可以帮助处理字符编码问题。 4. 数字处理:识别数字部分可能相对简单,因为...

    乱码 编码方式解决 gbk ISO8859-1 utf8 编码

    3. **软件编码识别错误**:部分软件可能无法准确识别文件的编码格式,尤其是在处理非标准编码或混合编码的文件时。 **解决方法**: 1. **手动指定编码**:在编程时,可以显式指定文件的编码格式,例如在Java中使用...

    ANSI+UTF-8解码.rar

    源码可能包含了函数或者模块,用于识别和转换这两种编码,帮助开发者处理混合编码的文本文件。 在实际开发中,处理混合编码的情况并不罕见,特别是在处理旧的数据或从不同来源获取的文本时。通过使用这些源码,...

    编码转换Veryzhou_1.02正式版.rar

    2. GBK到UTF-8的转换:许多现代网络标准和编程语言默认使用UTF-8,因此将GBK编码的文本转换为UTF-8可以使其在更广泛的环境中正常工作。 3. Unicode到其他编码的转换:根据用户需求,该工具可能还支持从Unicode转换到...

    php版mysql大数据库备份和恢复工具

    4.虽然程序目前支持GBK、BIG5、UTF8之间的编码转换,但这种转换不是安全的.首先你的目标导入服务器要支持iconv,即在导入时如果"编码转换功能"提示为支持,则可以使用此功能.反之则不可以.其次,转换时的数据必须是"干净...

    新编码转换大全模块+应用例程.rar

    - **多语言混合**:处理包含多种语言的文本时,需要更复杂的转换策略。 - **不完整编码**:部分文本可能没有正确标识其编码,需要猜测或手动指定。 - **性能优化**:大规模文本转换时,效率和内存管理是关键。 ...

    Windows代码页转换与简繁体互换

    简繁体中文的转换涉及到字符集如GBK(简体)和Big5(繁体)之间的转换,也可以通过Unicode(UTF-8、UTF-16等)作为中介进行转换。转换过程中需要正确识别输入文本的原始编码,然后选择合适的转换方法,确保转换后...

    QRCode二维码生成DLL 解决全中文乱码 源码奉上,经过Reflector反编译分析

    为了解决这个问题,开发者需要确保在生成二维码时,正确地将中文字符串转换为二维码可识别的编码格式,如UTF-8,并在解码时同样使用正确的编码还原数据。 Reflector是一款强大的.NET反编译工具,它可以帮助我们查看...

    新编码转换大全

    UTF-8是目前最常用的,因为它在保持向后兼容的同时,可以高效地存储英文和中文混合的文本,且大部分网页都采用UTF-8编码。 编码转换的必要性主要体现在以下几点: 1. 兼容性问题:不同的软件、系统或数据库可能...

    简体繁体中文转换包源码

    1. 处理混合文本:在转换时,可能需要处理简繁体混杂的文本,确保正确识别和转换。 2. 特殊字符和符号:某些特殊字符和符号在简繁体中可能有所不同,需要特别处理。 3. 性能优化:对于大量文本的转换,代码需要进行...

    易语言取混合文本长度源码-易语言

    易语言的“取混合文本长度”函数,其核心在于正确地识别和处理各种字符编码,特别是在GB2312、GBK、UTF-8等编码环境下。这个函数能够根据所使用的编码方式,正确计算出字符串中所有字符的实际长度,对于显示和处理多...

Global site tag (gtag.js) - Google Analytics