Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2151137
  • 博文数量: 361
  • 博客积分: 10828
  • 博客等级: 上将
  • 技术积分: 4161
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-20 14:34
文章分类

全部博文(361)

文章存档

2011年(132)

2010年(229)

分类: LINUX

2011-09-23 09:27:58

前言

很多人用source insight 打开某些源码文件时,汉字显示为一堆乱码。这个问题是因为编码方式不同。记事本和一些编辑器默认编码方式是ANSI,在这种方式下输入汉字,其实就是GB系列的编码方式。不幸的是,广收欢迎的代码查看工具Source insight 虽然支持汉字,但是它不支持UTF-8。笔者感到疑惑的是,当初开发source insight的这帮人现在哪里去了?为何不继续开发?这么好的工具,却不再更新了,实在让人可惜。

可惜归可惜,程序还是要看。乱码怎么办?很多人用笨方法,用记事本打开源代码,再另存为ANSI格式的文件。如果文件只有几个,倒是既简单又实惠,然而,当你碰到成百上千的代码文件都是UTF-8时,你就会觉得这是梦魇了。

不过,不要怕。现在,完美的解决方法来了。(貌似跟做广告一样)

概述

本程序是参考网上源代码修改而成。感谢原作者将该代码开源,我的工作只需在他的基础上进行修改就可以了,省去了大量的工作,使得我花了一个下午的时间就改成我所想要的程序。这就是开源的好处。所以说开源能帮助人们更快的开发出更好的软件,开源万岁。希望看到本文的读者,也能为开源事业贡献自己的一份力量。虽然说,此类代码到处都有,不足为奇,但这个代码在我改进之后,还是具有一些优点:

l         命令行执行  改进前的程序只能单独执行,根据提示输入参数和要转换的目录或文件;改进后的程序可集成到编辑器,集成开发环境(IDE)。下文将会介绍如何集成到source insight中。

l         智能识别编码方式  原来的程序不能识别编码方式。如果转换时选择了一个非UTF-8编码的文件,转换后就成了乱码;改进后的程序能智能识别编码方式,无论是UTF-8文件是BOM格式还是非BOM格式,都能识别。对于纯ASCII码的文件,也能识别。

l         支持批处理  改进前的程序有bug,对目录支持不完善;改进后的程序能很好的支持批处理。

 

目前,这个程序只针对源代码文件编写,支持后缀名为 .c .cpp .cxx .h .xml .java .txt等文件。如确实有需要,今后将支持更多类型的文件编码格式转换。

 

如何集成到 source insight?

下面,先介绍如何集成到 source insight里。本人使用的汉化版,如英文版请对照执行。

文件转换命令    该命令能将当前打开的文件进行编码转换。很简单,步骤如下:

source insight里,选择 “选项”“自定义命令”,弹出对话框后,点击“添加”,输入新命令名 CodeConvert File 。确定后,点击“浏览”,选择我们的codeConvert.exe程序路径。在输入框里加上参数” –u2g %f” (注意空格,双引号不要)。

这样,这个文件转换命令就添加成功。打开某个文件,按照上面步骤,选择该自定义命令点击“运行”,即可进行转换。

目录转换命令    该命令能将当前打开的文件所在的文件夹进行编码转换。步骤同上,只是在输入框里的参数改为” –u2g %d” (注意空格,双引号不要)。

怎么样?在source insight里点几下,就能转换了。混沌世界一下子清晰了。

主要源码部分

这是检测文件是否是UTF-8格式的函数,其他部分不再一一列出,请参考源代码。

  1. /* ! detect if the fiel is UTF-8 code
  2. /param LPCTSTR filename
  3. /return true/false
  4. */

  5. bool detect_utf8file(LPCTSTR filename)
  6. {
  7.     const unsigned char BOM[3] = {0xEF, 0xBB, 0xBF};
  8.     int count_good_utf = 0;
  9.     int count_bad_utf = 0;
  10.     int begin = 0;
  11.     char buf[3] = {0, };
  12.     CStdioFile file_r ;

  13.     if (!file_r.Open((char*)(LPCTSTR)filename, CStdioFile::modeReadWrite))
  14.         return false;


  15.     file_r.Read(buf, 3);
  16.     if (!strncmp(buf, (char *)BOM, 3))
  17.     {
  18.         std::cout << "this is utf(BOM). " << endl;
  19.         file_r.Close();

  20.         return true;
  21.     }
  22.     else // detect the whole file
  23.     {
  24.         // UTF-8 text encoding auto-detection
  25.         // count the following pairs of consecutive bytes as shown in the table:
  26.         // 11.. 10.. good
  27.         // 00.. 10.. bad
  28.         // 10.. 10.. don't care
  29.         // 11.. 00.. bad
  30.         // 11.. 11.. bad
  31.         // 00.. 00.. don't care
  32.         // 10.. 00.. don't care
  33.         // 00.. 11.. don't care
  34.         // 10.. 11.. don't care
  35.         char current_byte, previous_byte;

  36.         file_r.SeekToBegin();
  37.         file_r.Read(&current_byte, 1);
  38.         previous_byte = current_byte;

  39.         while (file_r.Read(&current_byte, 1))
  40.         {
  41.             if ((current_byte & 0xC0) == 0x80)
  42.             {
  43.                 if ((previous_byte & 0xC0) == 0xC0)
  44.                 {
  45.                     count_good_utf ++;
  46.                 }
  47.                 else if ((previous_byte & 0x80) == 0x00)
  48.                 {
  49.                     count_bad_utf ++;
  50.                 }
  51.             }
  52.             else if ((previous_byte & 0xC0) == 0xC0)
  53.             {
  54.                 count_bad_utf ++;
  55.             }
  56.             previous_byte = current_byte;
  57.         }
  58.         // the comparison ">=" handles pure ASCII files as UTF-8,
  59.         // replace it with ">" to change that

  60.         if (count_good_utf > count_bad_utf)
  61.         {
  62.             file_r.Close();
  63.             std::cout << "the code of this file is utf(no BOM). " << endl;
  64.             return true;
  65.         }
  66.         else if (count_good_utf == count_bad_utf)
  67.         {
  68.             file_r.Close();
  69.             std::cout << "the code of this file is pure ASCII file as UTF-8. " << endl;
  70.             return true;
  71.         }
  72.         else
  73.         {
  74.             file_r.Close();
  75.             std::cout << "the code of this file is not utf. " << endl;
  76.             return false;
  77.         }
  78.     }
  79. }

程序虽然能运行,但是我相信还有bug,还可以完善。本人知识有限,如有不当之处还请多多指正,大家共同进步。源代码在 ,好像CSDN只能在那里上传代码。

转自:http://blog.csdn.net/flylonginsky/article/details/4670188

阅读(23286) | 评论(0) | 转发(3) |
给主人留下些什么吧!~~