iconv用法解读
来源:互联网 发布:au软件录音保存 编辑:程序博客网 时间:2024/05/16 04:18
iconv是一个字符集转换函数,原型为:
size_t iconv(iconv_t cd,
char **inbuf, size_t *inbytesleft,
char **outbuf, size_t *outbytesleft);
// 传递给do_convert的in_buf,所有字节数(in_buf_size指定)都是可以转换成功的static int do_convert(iconv_t cd, const char* from, size_t from_size, std::string* to){ char* in_buf_ptr = const_cast<char*>(from); size_t in_bytes_left = from_size; size_t out_bytes = in_bytes_left*3 + 1; size_t out_bytes_left = out_bytes; std::string out(out_bytes_left, '\0'); char* out_buf_start = const_cast<char*>(out.c_str()); char* out_buf_ptr = out_buf_start; int bytes = iconv(cd, &in_buf_ptr, &in_bytes_left, &out_buf_ptr, &out_bytes_left); if (-1 == bytes) return errno; to->assign(out_buf_start, out_bytes-out_bytes_left); return 0;}// 可忽略不能转换的部分,// 也可以在结果中保留不能被转换的部分// 详细实现可以浏览:// https://github.com/eyjian/mooon/blob/master/common_library/src/utils/charset_utils.cppvoid CCharsetUtils::convert(const std::string& from_charset, const std::string& to_charset, const std::string& from, std::string* to, bool ignore_error, bool skip_error) throw (CException){ std::string result; // 用来保存处理后的内容 char* in_buf = const_cast<char*>(from.c_str()); size_t in_bytes = from.size(); // 需要处理的总字节数 size_t in_bytes_left = in_bytes; // 剩余的未被处理的字节数 iconv_t cd = iconv_open(to_charset.c_str(), from_charset.c_str()); if ((iconv_t)(-1) == cd) { THROW_EXCEPTION(strerror(errno), errno); } while (in_bytes_left > 0) { int errcode; size_t out_bytes = in_bytes_left * 3 + 1; // 保证足够大 size_t out_bytes_left = out_bytes; std::string out(out_bytes_left, '\0'); char* out_buf = const_cast<char*>(out.c_str()); char* out_buf_start = out_buf; char* in_buf_start = in_buf; // 如果成功,返回值bytes为0 // 如果成功,in_buf指向in的结尾符,即'\0',同时in_bytes_left值为0 // 如果失败,in_buf指向未能转换的起始地址,而in_bytes_left值为剩余的未被转换的(可能含有可转换的)字节数 // 如果成功,则out_bytes-out_bytes_left值为转换后的字节数 // 如果成功,则out_buf_start存储了被转换后的结果,有效长度为out_bytes-out_bytes_left int bytes = iconv(cd, &in_buf, &in_bytes_left, &out_buf, &out_bytes_left); if (bytes != -1) { result.append(out_buf_start, out_bytes-out_bytes_left); break; } else if (!ignore_error) { errcode = errno; iconv_close(cd); THROW_EXCEPTION(strerror(errcode), errcode); } else { // EILSEQ An invalid multibyte sequence has been encountered in the input. // EINVAL An incomplete multibyte sequence has been encountered in the input. if ((errno != EINVAL) && (errno != EILSEQ)) { // E2BIG There is not sufficient room at *outbuf. errcode = errno; iconv_close(cd); THROW_EXCEPTION(strerror(errcode), errcode); } else { // in_buf之前部分是可以转换的 if (in_buf != in_buf_start) { std::string str; errcode = do_convert(cd, in_buf_start, in_buf-in_buf_start, &str); if (errcode != 0) { iconv_close(cd); THROW_EXCEPTION(strerror(errcode), errcode); } result.append(str); } // skip_error决定未能被转换的是否出现在结果当中 if (!skip_error) { result.append(in_buf, 1); } // 往前推进 --in_bytes_left; // 将导致while语句结束 ++in_buf; } } } if (-1 == iconv_close(cd)) { THROW_EXCEPTION(strerror(errno), errno); } // 不能直接使用to,因为to可能就是from *to = result;}void CCharsetUtils::gbk_to_utf8(const std::string& from, std::string* to, bool ignore_error, bool skip_error) throw (CException){ convert("gbk", "utf-8", from, to, ignore_error, skip_error);}void CCharsetUtils::utf8_to_gbk(const std::string& from, std::string* to, bool ignore_error, bool skip_error) throw (CException){ convert("utf-8", "gbk", from, to, ignore_error, skip_error);}void CCharsetUtils::gb2312_to_utf8(const std::string& from, std::string* to, bool ignore_error, bool skip_error) throw (CException){ convert("gb2312", "utf-8", from, to, ignore_error, skip_error);}void CCharsetUtils::utf8_to_gb2312(const std::string& from, std::string* to, bool ignore_error, bool skip_error) throw (CException){ convert("utf-8", "gb2312", from, to, ignore_error, skip_error);}
0 0
- iconv用法解读
- iconv用法
- iconv用法
- iconv的用法
- iconv 用法封装
- iconv()函数的用法
- iconv
- iconv
- iconv
- iconv
- iconv
- iconv
- iconv
- iconv
- linux shell 中iconv的用法
- iconv用法,编码转换(一)
- iconv用法,编码转换(二)
- linux下iconv()函数的用法
- 百度前端笔试题及答案
- python 编码注释问题
- struts2的#$%区别!
- JPA EntityManager详解
- 《2》观察者模式
- iconv用法解读
- perl 微信 获取消息
- Java Code Examples for org.apache.commons.codec.binary.Base64InputStream
- java学习之路
- android Universal-Image-Loader oom:关于bitmap的优化及其他优化
- 大数据量时Mysql的优化要点
- js 方法的动态调用 apply的用法
- iOS [[UIDevice currentDevice] systemName]的返回值
- 初遇Express(小demo)