iconv_open() 在 Solaris 8 上返回 EINVAL
iconv_open() returning EINVAL on Solaris 8
在Solaris 8中,看起来iconv*()
函数族被破坏了,只支持单字节字符集和UTF-8
之间的转换,这可以使用此代码示例进行验证:
#include <stdio.h>
#include <errno.h>
#include <iconv.h>
#if defined(__sun) && defined(__SVR4)
#define CP1251 "ansi-1251"
#define ISO_8859_5 "ISO8859-5"
#else
#define CP1251 "CP1251"
#define ISO_8859_5 "ISO-8859-5"
#endif
void iconv_open_debug(const char *, const char *);
int main() {
iconv_open_debug(CP1251, CP1251);
iconv_open_debug(CP1251, ISO_8859_5);
iconv_open_debug(CP1251, "KOI8-R");
iconv_open_debug(CP1251, "UTF-8");
iconv_open_debug(CP1251, "WCHAR_T");
iconv_open_debug(ISO_8859_5, CP1251);
iconv_open_debug(ISO_8859_5, ISO_8859_5);
iconv_open_debug(ISO_8859_5, "KOI8-R");
iconv_open_debug(ISO_8859_5, "UTF-8");
iconv_open_debug(ISO_8859_5, "WCHAR_T");
iconv_open_debug("KOI8-R", CP1251);
iconv_open_debug("KOI8-R", ISO_8859_5);
iconv_open_debug("KOI8-R", "KOI8-R");
iconv_open_debug("KOI8-R", "UTF-8");
iconv_open_debug("KOI8-R", "WCHAR_T");
iconv_open_debug("UTF-8", CP1251);
iconv_open_debug("UTF-8", ISO_8859_5);
iconv_open_debug("UTF-8", "KOI8-R");
iconv_open_debug("UTF-8", "UTF-8");
iconv_open_debug("UTF-8", "WCHAR_T");
iconv_open_debug("WCHAR_T", CP1251);
iconv_open_debug("WCHAR_T", ISO_8859_5);
iconv_open_debug("WCHAR_T", "KOI8-R");
iconv_open_debug("WCHAR_T", "UTF-8");
iconv_open_debug("WCHAR_T", "WCHAR_T");
return 0;
}
void iconv_open_debug(const char *from, const char *to) {
errno = 0;
if (iconv_open(to, from) == (iconv_t) -1) {
fprintf(stderr, "iconv_open(\"%s\", \"%s\") FAIL: errno = %d\n", to, from, errno);
perror("iconv_open()");
} else {
fprintf(stdout, "iconv_open(\"%s\", \"%s\") PASS\n", to, from);
}
}
只打印
iconv_open("UTF-8", "ansi-1251") PASS
iconv_open("UTF-8", "ISO8859-5") PASS
iconv_open("UTF-8", "KOI8-R") PASS
iconv_open("ansi-1251", "UTF-8") PASS
iconv_open("ISO8859-5", "UTF-8") PASS
iconv_open("KOI8-R", "UTF-8") PASS
到 stdout 和 returns EINVAL
对于其他对。请注意,即使转换为相同的字符集(例如 UTF-8 -> UTF-8)也不支持。
问题
- 任何人都可以参考描述
iconv.h
的 Solaris 版本限制的文档吗?
- 如何根据 GNU
libiconv
将 wchar_t*
转换为单字节或多字节字符串 w/o? wcstombs()
会 很好,除了它依赖于当前语言环境的字符集,而我想要使用特定字符集将宽字符串转换为常规字符串,可能与默认字符集不同.
运行 sdtconvtool
显示支持大多数遗留代码页。
在使用 truss -u libc::iconv_open
重新 运行 相同的实用程序后,我了解到从一种单字节编码到另一种单字节编码的转换分两步完成,中间转换为 UTF-8
.
说到从 "WCHAR_T"
的转换,iconv(3)
也支持它,但是 "UCS-4"
应该用作源字符集名称,因为 sizeof(wchar_t)
在 Solaris 上是 4 (对于 x86 和 SPARC)。
在Solaris 8中,看起来iconv*()
函数族被破坏了,只支持单字节字符集和UTF-8
之间的转换,这可以使用此代码示例进行验证:
#include <stdio.h>
#include <errno.h>
#include <iconv.h>
#if defined(__sun) && defined(__SVR4)
#define CP1251 "ansi-1251"
#define ISO_8859_5 "ISO8859-5"
#else
#define CP1251 "CP1251"
#define ISO_8859_5 "ISO-8859-5"
#endif
void iconv_open_debug(const char *, const char *);
int main() {
iconv_open_debug(CP1251, CP1251);
iconv_open_debug(CP1251, ISO_8859_5);
iconv_open_debug(CP1251, "KOI8-R");
iconv_open_debug(CP1251, "UTF-8");
iconv_open_debug(CP1251, "WCHAR_T");
iconv_open_debug(ISO_8859_5, CP1251);
iconv_open_debug(ISO_8859_5, ISO_8859_5);
iconv_open_debug(ISO_8859_5, "KOI8-R");
iconv_open_debug(ISO_8859_5, "UTF-8");
iconv_open_debug(ISO_8859_5, "WCHAR_T");
iconv_open_debug("KOI8-R", CP1251);
iconv_open_debug("KOI8-R", ISO_8859_5);
iconv_open_debug("KOI8-R", "KOI8-R");
iconv_open_debug("KOI8-R", "UTF-8");
iconv_open_debug("KOI8-R", "WCHAR_T");
iconv_open_debug("UTF-8", CP1251);
iconv_open_debug("UTF-8", ISO_8859_5);
iconv_open_debug("UTF-8", "KOI8-R");
iconv_open_debug("UTF-8", "UTF-8");
iconv_open_debug("UTF-8", "WCHAR_T");
iconv_open_debug("WCHAR_T", CP1251);
iconv_open_debug("WCHAR_T", ISO_8859_5);
iconv_open_debug("WCHAR_T", "KOI8-R");
iconv_open_debug("WCHAR_T", "UTF-8");
iconv_open_debug("WCHAR_T", "WCHAR_T");
return 0;
}
void iconv_open_debug(const char *from, const char *to) {
errno = 0;
if (iconv_open(to, from) == (iconv_t) -1) {
fprintf(stderr, "iconv_open(\"%s\", \"%s\") FAIL: errno = %d\n", to, from, errno);
perror("iconv_open()");
} else {
fprintf(stdout, "iconv_open(\"%s\", \"%s\") PASS\n", to, from);
}
}
只打印
iconv_open("UTF-8", "ansi-1251") PASS
iconv_open("UTF-8", "ISO8859-5") PASS
iconv_open("UTF-8", "KOI8-R") PASS
iconv_open("ansi-1251", "UTF-8") PASS
iconv_open("ISO8859-5", "UTF-8") PASS
iconv_open("KOI8-R", "UTF-8") PASS
到 stdout 和 returns EINVAL
对于其他对。请注意,即使转换为相同的字符集(例如 UTF-8 -> UTF-8)也不支持。
问题
- 任何人都可以参考描述
iconv.h
的 Solaris 版本限制的文档吗? - 如何根据 GNU
libiconv
将wchar_t*
转换为单字节或多字节字符串 w/o?wcstombs()
会 很好,除了它依赖于当前语言环境的字符集,而我想要使用特定字符集将宽字符串转换为常规字符串,可能与默认字符集不同.
运行 sdtconvtool
显示支持大多数遗留代码页。
在使用 truss -u libc::iconv_open
重新 运行 相同的实用程序后,我了解到从一种单字节编码到另一种单字节编码的转换分两步完成,中间转换为 UTF-8
.
说到从 "WCHAR_T"
的转换,iconv(3)
也支持它,但是 "UCS-4"
应该用作源字符集名称,因为 sizeof(wchar_t)
在 Solaris 上是 4 (对于 x86 和 SPARC)。