在windows下使用iconv(跨平台的编码转换库的选择)

 跨平台的编码转换库,好吧。第一反应是ibm的icu库,因为之前用过的boost的regexp用的就是它。 第二反应是自己包装一个,因为之前完成了很多跨平台的包装,再实现一个并不难。第三反应Google。结果看到gnu的iconv库可以有woe的版本。而icu的大小是10MB,iconv的静态库不到1MB,所以还是用它吧。

 这儿需要提到的是第一次我自己coding的时候,少考虑了EILSEQ(An invalid multibyte sequence has been encountered in the input.)的情况。所以贴一个我认为可以用在生产环境的实现:

// charsetconv.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include #include #include #include #include #include #include #ifndef ICONV_CONST # define ICONV_CONST const #endif int convert(const char *from, const char *to, char* save, int savelen, char *src, int srclen) { iconv_t cd; char *inbuf = src; char *outbuf = save; size_t outbufsize = savelen; int status = 0; size_t savesize = 0; size_t inbufsize = srclen; const char* inptr = inbuf; size_t insize = inbufsize; char* outptr = outbuf; size_t outsize = outbufsize; cd = iconv_open(to, from); iconv(cd,NULL,NULL,NULL,NULL); if (inbufsize == 0) { status = -1; goto done; } while (insize > 0) { size_t res = iconv(cd,(ICONV_CONST char**)&inptr,&insize,&outptr,&outsize); if (outptr != outbuf) { int saved_errno = errno; int outsize = outptr - outbuf; strncpy(save+savesize, outbuf, outsize); errno = saved_errno; } if (res == (size_t)(-1)) { if (errno == EILSEQ) { int one = 1; iconvctl(cd,ICONV_SET_DISCARD_ILSEQ,&one); status = -3; } else if (errno == EINVAL) { if (inbufsize == 0) { status = -4; goto done; } else { break; } } else if (errno == E2BIG) { status = -5; goto done; } else { status = -6; goto done; } } } status = strlen(save); done: iconv_close(cd); return status; } int _tmain(int argc, _TCHAR* argv[]) { std::ifstream fs("c://1.txt"); if (!fs.fail()) { std::istreambuf_iterator beg(fs), end; std::vector buf(beg, end); std::string content(buf.begin(), buf.end()); std::vector tobuf(2 * content.length() + 16); //std::vector tobuf2; std::size_t tolen = convert("UTF-8//IGNORE","gb2312", (char *)&tobuf[0], tobuf.size(), (char *)content.c_str(), content.length()); if (tolen < 0) { std::cerr << "Error/n"; } else{ tobuf.resize(tolen); std::cout << std::string(tobuf.begin(), tobuf.end()) << std::endl; } //tlconv(tobuf2, (const unsigned char *)&tobuf[0], tobuf.size()); } return 0; }

你可能感兴趣的:(跨平台开发,跨平台,windows,null,string,ibm,google)