C convert iso ISO?8859-1 to UTF-8 with libconv
我需要将拉丁ISO?8859-1字符编码为UTF-8(以及相反的操作)。
我首先使用了这个答案是否有办法将UTF8转换为iso-8859-1?执行该操作并起作用;
现在,我想使用提供所有转换机制的libiconv,它应该可以帮助我简化代码。
我遵循了此处提供的示例:
https://www.lemoda.net/c/iconv-example/iconv-example.html
我写了一个看起来像这样的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | char *iconvISO2UTF8(char *iso) { iconv_t iconvDesc = iconv_open ("ISO?8859-1","UTF-8//TRANSLIT//IGNORE"); if (iconvDesc == (iconv_t) - 1) { /* Something went wrong. */ if (errno == EINVAL) fprintf(stderr,"conversion from '%s' to '%s' not available","ISO?8859?1","UTF-8"); else fprintf(stderr,"LibIcon initialization failure"); return NULL; } size_t iconv_value; char * utf8; size_t len; size_t utf8len; char * utf8start; int len_start; len = strlen (iso); if (! len) { fprintf(stderr,"iconvISO2UTF8: input String is empty."); return NULL; } /* Assign enough space to put the UTF-8. */ utf8len = 2 * len; utf8 = calloc (utf8len, sizeof (char)); if (! utf8) { fprintf(stderr,"iconvISO2UTF8: Calloc failed."); return NULL; } /* Keep track of the variables. */ utf8start = utf8; len_start = len; iconv_value = iconv (iconvDesc, & iso, & len, & utf8, & utf8len); /* Handle failures. */ if (iconv_value == (size_t) - 1) { switch (errno) { /* See"man 3 iconv" for an explanation. */ case EILSEQ: fprintf(stderr,"iconv failed: Invalid multibyte sequence, in string '%s', length %d, out string '%s', length %d\ ", iso, (int) len, utf8start, (int) utf8len); break; case EINVAL: fprintf(stderr,"iconv failed: Incomplete multibyte sequence, in string '%s', length %d, out string '%s', length %d\ ", iso, (int) len, utf8start, (int) utf8len); break; case E2BIG: fprintf(stderr,"iconv failed: No more room, in string '%s', length %d, out string '%s', length %d\ ", iso, (int) len, utf8start, (int) utf8len); break; default: fprintf(stderr,"iconv failed, in string '%s', length %d, out string '%s', length %d\ ", iso, (int) len, utf8start, (int) utf8len); } return NULL; } if(iconv_close (iconvDesc) != 0) { fprintf(stderr,"libicon close failed: %s", strerror (errno)); } return utf8start; } |
当我用诸如" abracadabra"之类的普通老式ascii字符来称呼此功能时,iconv可以工作。
但是,一旦我向其中发送突出的字符,例如"éàèü??"然后iconv()调用失败,并显示EILSEQ代码:
iconv failed: Invalid multibyte sequence, in string 'éàèü??', length
6, out string '', length 12
这是一个示例主程序,当存储在以ISO 8859-1编码的源文件中并在以ISO 8859-1作为默认字符集的linux系统上编译时,它会崩溃:
1 2 3 4 5 6 7 8 9 10 11 |
是否可以使用iconv运行这种转换?
如果是,此代码有什么问题?
请仔细阅读
1 | iconv_t iconv_open(const char *tocode, const char *fromcode); |
如果您要从ISO 8859-1转换为UTF-8,则可能会出现问题:
1 | iconv_t iconvDesc = iconv_open ("ISO?8859-1","UTF-8//TRANSLIT//IGNORE"); |
应该说
1 | iconv_t iconvDesc = iconv_open ("UTF-8//TRANSLIT//IGNORE","ISO?8859-1"); |