日文euc-jp编码转换——谈codepage 51932


EUC-JP编码常见于日文网页、数据库。但是,用过GNU的recode或者iconv的可能会有体会,就是往往一个euc-jp编码的文件并不能成功地转换为其他编码格式,碰到像罗马数字这样的字符就会出错。这是因为这些都属于euc-jp标准的扩充,虽然实际在使用但是GNU的工具并不支持。


在Windows下,可以采用MultiByteToWideChar和WideCharToMultiByte来转换euc-jp编码的文件。这里euc-jp编码对应codepage 20932。但是这样仍然不能覆盖全部的字符集。包含全部扩充文字(NEC選定IBM拡張文字等)的euc-jp编码对应于codepage 51932,但是Windows的API并不支持。据说只有IE使用的MLang的ConvertINetString之类的函数才能使用codepage 51932。但是我试过在XP英文版下用gcc编译的程序仍然不能使用cp51932。


测试代码1:
// gcc -Wall conve.c mlang.dll
#include
 
 
  
  
#include
  
  
   
   
#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
#define MAX_BUF 256
extern HRESULT ConvertINetString(LPDWORD, DWORD, DWORD, LPCSTR, LPINT, LPSTR, LPINT);


int main(int argc, char *argv[])
{
    DWORD mode = 0, srcenc, dstenc;
    BYTE src[MAX_BUF], dst[MAX_BUF*2];
    UINT srclen, dstlen;
    FILE *fp, *gp;
    int line = 0;

    srcenc = 65001;
    dstenc = 936;
    if (argc > 1)
        srcenc = atoi(argv[1]);
    if (argc > 2)
        dstenc = atoi(argv[2]);
    printf("From %lu to %lu/n", srcenc, dstenc);

    fp = stdin;
    gp = fopen("log.tmp", "w");
    while (!feof(fp) && fgets(src, MAX_BUF, fp))
    {
        srclen = strlen(src);
        if (srclen > 0 && src[srclen - 1] == '/n')
            --srclen;
        printf("Line %d: ", ++line);
        fprintf(gp, "Line %d: %.*s/n", line, srclen, src);
        fflush(gp);
        switch (ConvertINetString(&mode, srcenc, dstenc, 
                                          src, &srclen, dst, &dstlen))
        {
            case S_OK:
                break;
            case S_FALSE:
                fprintf(stderr, "The specified conversion is not supported on the system./n");
                //exit(1);
                break;
            case E_FAIL:
                fprintf(stderr, "An error occurred./n");
                break;
        }
        printf("%d/n", dstlen);
        printf("%.*s/n", dstlen, dst);
    }

    fclose(gp);

    return 0;
}

     
     
    
    
   
   
  
  
 
 


测试代码2:
// gcc -Wall test.c -lole32 -luuid
// needs patched mlang-uuid.c to build libuuid
#include
 
 
  
  
#include
  
  
   
   
#include
   
   
    
    
#include
    
    
     
     
#include
     
     
      
      
#include
      
      
        #include 
       
         #define MAX_BUF 256 int main(int argc, char *argv[]) { IMultiLanguage *p; DWORD mode = 0, srcenc, dstenc; BYTE src[MAX_BUF], dst[MAX_BUF*2]; UINT srclen, dstlen; FILE *fp; int line = 0; CoInitialize(NULL); if ( FAILED(CoCreateInstance(&CLSID_CMultiLanguage ,NULL, CLSCTX_ALL, &IID_IMultiLanguage2 ,(void**)&p)) ) { return -1; } srcenc = 65001; dstenc = 936; if (argc > 1) srcenc = atoi(argv[1]); if (argc > 2) dstenc = atoi(argv[2]); printf("From %lu to %lu/n", srcenc, dstenc); fp = stdin; while (!feof(fp) && fgets(src, MAX_BUF, fp)) { srclen = strlen(src); if (srclen > 0 && src[srclen - 1] == '/n') --srclen; printf("Line %d: ", ++line); //assert( p->lpVtbl->ConvertString != NULL); switch ( p->lpVtbl->ConvertString(p, &mode, srcenc, dstenc, src, &srclen, dst, &dstlen) ) { case S_OK: break; case S_FALSE: fprintf(stderr, "The specified conversion is not supported on the system./n"); //exit(1); break; case E_FAIL: fprintf(stderr, "An error occurred./n"); break; } printf("%d/n", dstlen); printf("%.*s/n", dstlen, dst); } p->lpVtbl->Release(p); CoUninitialize(); return 0; } 
        
      
     
     
    
    
   
   
  
  
 
 


既然用API的方法不行,那么究竟怎么办呢?


解决方法其实很简单:打上日本人做的libiconv补丁就行了。地址: http://www2d.biglobe.ne.jp/~msyk/software/libiconv-patch.html。然后就可以使用CP51932作为完整的euc-jp编码来进行转换了。这就跟iconv的GBK不完整,用GB18030就全了类似。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值