在SOLARIS下装了个libiconv库,编译以下程序为:
gcc -L/usr/local/iconv/lib -o conv conv.c -liconv
#include "/usr/local/iconv/include/iconv.h"
#include <strings.h>
#define BUFLEN 200
char inbuf[BUFLEN];
char outbuf[BUFLEN];
char* pin = inbuf;
char* pout = outbuf;
int inlen;
int outlen = BUFLEN;
main(int argc, char **argv)
{
iconv_t cd;
ssize_t n;
bzero(inbuf, BUFLEN);
strncpy(inbuf, argv[1], BUFLEN);
if((cd = iconv_open(argv[3], argv[2])) == (iconv_t)-1) //argv2 = from, argv3 =to
return;
printf("convsing.........\n");
inlen = strlen(inbuf);
printf("cd is %d, inlen = %d\n", cd, inlen);
if((n = iconv(cd, (const char **)&pin, &inlen, &pout, &outlen)) == (ssize_t)(-
1)){
perror("iconv error\n");
return;
}
printf("Output: %s,n= %d,inlen=%d,outlen=%d\n", pout,n,inlen,outlen);
iconv_close(cd);
}
运行:
./conv 测试 GB2312 UTF-8
convsing.........
cd is 134864, inlen = 4
Output: ,n= 0,inlen=0,outlen=194
既然iconv()也没出错,而且inlen已经-为0,说明已经作过转换了,为什么n=0,pout没有内容输出呢?
| bigluo 回复于:2003-06-08 12:16:58
| 我对solaris不是很熟悉,但是在linux中,iconv的正确转换需要glibc有相应的码表的支持。你可以检查一下你的solaris中的libc有gb2312->utf8的码表吗?
| | chdonald 回复于:2003-06-08 15:16:51
| 我查过了,支持的
iconv -l
而且用它提供的iconv命令也可以正确把一个GB2312文件的内容转换成UTF-8的
| | bigluo 回复于:2003-06-08 15:57:19
| 我在三年前在RH linux 6.2下做过这些,现在真的记得不是特别清楚了,当时是根据台湾cle网站上的中文化文章做的,那儿对宽字节和iconv讲的很清楚,你可以去查阅一下。
| | gadfly 回复于:2003-06-08 23:14:33
| 是这样子的。
iconv的man有点问题。iconv返回的实际上不是成功的数目。0只是说明成功。
最好先bzero outbuf, 另外,转化的不一定是可打印字符,你可以打印字符串的ascii码看看。
| | libad 回复于:2003-06-10 17:03:24
| 我在LDAP中配置了中文,在solaris下面用C取出后是乱码。
gadfly说让我到这来请教各位。
1)我solaris下面没有装libiconv库。
应该去那里找这个库来安装?
2)听bigluo说:
iconv的正确转换需要glibc有相应的码表的支持。你可以检查一下你的solaris中的libc有gb2312->utf8的码表吗?
我运行:
iconv -f UTF-8 -t GB2312 my.txt
提示:
不支持到 GB2312 的 UTF-8
好象是没有相应的码表,我应该怎么办,去那里去安装呀?
| | gadfly 回复于:2003-06-10 18:04:45
| 1.需要装glibc-devel软件包
2.我的solaris装了这几个包
ALE SUNWciu8 Simplified Chinese (EUC) iconv modules for UTF-8
ALE SUNWciu8x Simplified Chinese (EUC) iconv modules for UTF-8 (64-bit)
ALE SUNWhiu8 Traditional Chinese iconv modules for UTF-8
ALE SUNWhiu8x Traditional Chinese (EUC) iconv modules for UTF-8 (64-bit)
另外这样是可以的
iconv -f UTF-8 -t gb2312 my.txt
| | libad 回复于:2003-06-10 18:11:34
| 斑竹:
glibc-devel软件包 去那里下载呀?
| | gadfly 回复于:2003-06-10 18:38:22
| 哦,在solaris上有个单独的libiconv
sunfreeware.com
| | chdonald 回复于:2003-06-10 20:06:30
| 没错,我就是下了这个包的。可是我的问题还没搞定,请大家帮忙!!
| | gadfly 回复于:2003-06-10 22:40:37
| 你现在做到哪一步出问题了?
| | gadfly 回复于:2003-06-10 23:40:40
| 我有稍微看了chdonald的代码发现最后printf有问题,pout在iconv会指向转换结束的位置,当然什么都没有打印。我稍微改了一下。你们自己测试看看。
我这边现在没法在终端输入中文。可以这样测试
./test_iconv 字符 gb2312 -t UTF-8
iconv -f gb2312 -t UTF-8 ccc
ccc内容
[code:1:07e2cc8cfb]
字符
[/code:1:07e2cc8cfb]
看看两个结果是否一样,然后对输出的串做反变换看看
[code:1:07e2cc8cfb]
/* gcc test_iconv -o test_iconv */
#include <stdio.h>
#include <iconv.h>
#define BUFLEN 200
char inbuf[BUFLEN];
char outbuf[BUFLEN];
char* pin = inbuf;
char* pout = outbuf;
int inlen;
int outlen = BUFLEN - 1;
void outbin(char * outbuf) {
char *p = outbuf;
if (!p) return;
while (*p) printf("%c", *p++);
printf("\n");
}
void usage(const char * prog) {
printf("Usage: %s string from_code to_code\n", basename(prog));
exit(-1);
}
int main(int argc, char **argv) {
iconv_t cd;
if (argc < 4) usage(argv[0]);
bzero(inbuf, 0, BUFLEN);
bzero(outbuf, 0, BUFLEN);
strncpy(inbuf, argv[1], BUFLEN);
if((cd = iconv_open(argv[3], argv[2])) < 0) return -1;
inlen = strlen(inbuf);
printf("inlen = %d, %s, pout addr is %p\n", inlen, inbuf, pout);
inlen++;
// iconv(cd, NULL, NULL, NULL, NULL);
if(iconv(cd, &pin, &inlen, &pout, &outlen) < 0)
return;
printf("outlen is %d, pout addr is %p, Output: %s\n", outlen, pout, outbuf);
// outbin(outbuf);
iconv_close(cd);
return 0;
}
[/code:1:07e2cc8cfb]
| | libad 回复于:2003-06-11 10:17:33
| 我去sunfreeware.com 下载了 libiconv-1.6.1-sol8-sparc-local
怎么安装呀?
| | gadfly 回复于:2003-06-11 11:50:36
| pkgadd -d libiconv*
| | chdonald 回复于:2003-06-11 20:59:21
| 是的,iconv返回0就说明字符序列全部已经转换成功,pin和pout指针都会变化的。
以下是例子:
[code:1:546c0e288d] #include <stdio.h>
#include <errno.h>
#include <string.h>
#include <iconv.h>
#include <stdlib.h>
/*
* For state-dependent encodings, changes the state of the conversion
* descriptor to initial shift state. Also, outputs the byte sequence
* to change the state to initial state.
* This code is assuming the iconv call for initializing the state
* won't fail due to lack of space in the output buffer.
*/
#define INIT_SHIFT_STATE(cd, fptr, ileft, tptr, oleft) \
{ \
fptr = NULL; \
ileft = 0; \
tptr = to; \
oleft = BUFSIZ; \
(void) iconv(cd, &fptr, &ileft, &tptr, &oleft); \
(void) fwrite(to, 1, BUFSIZ - oleft, stdout); \
}
int
main(int argc, char **argv)
{
iconv_t cd;
char from[BUFSIZ], to[BUFSIZ];
char *from_code, *to_code;
char *tptr;
const char *fptr;
size_t ileft, oleft, num, ret;
if (argc != 3) {
(void) fprintf(stderr,
"Usage: %s from_codeset to_codeset\\n", argv[0]);
return (1);
}
from_code = argv[1];
to_code = argv[2];
cd = iconv_open((const char *)to_code, (const char *)from_code);
if (cd == (iconv_t)-1) {
/*
* iconv_open failed
*/
(void) fprintf(stderr,
"iconv_open(%s, %s) failed\\n", to_code, from_code);
return (1);
}
ileft = 0;
while ((ileft +=
(num = fread(from + ileft, 1, BUFSIZ - ileft, stdin))) > 0) {
if (num == 0) {
/*
* Input buffer still contains incomplete character
* or sequence. However, no more input character.
*/
/*
* Initializes the conversion descriptor and outputs
* the sequence to change the state to initial state.
*/
INIT_SHIFT_STATE(cd, fptr, ileft, tptr, oleft);
(void) iconv_close(cd);
(void) fprintf(stderr, "Conversion error\\n");
return (1);
}
fptr = from;
for (;;) {
tptr = to;
oleft = BUFSIZ;
ret = iconv(cd, &fptr, &ileft, &tptr, &oleft);
if (ret != (size_t)-1) {
/*
* iconv succeeded
*/
/*
* Outputs converted characters
*/
(void) fwrite(to, 1, BUFSIZ - oleft, stdout);
break;
}
/*
* iconv failed
*/
if (errno == EINVAL) {
/*
* Incomplete character or shift sequence
*/
/*
* Outputs converted characters
*/
(void) fwrite(to, 1, BUFSIZ - oleft, stdout);
/*
* Copies remaining characters in input buffer
* to the top of the input buffer.
*/
(void) memmove(from, fptr, ileft);
/*
* Tries to fill input buffer from stdin
*/
break;
} else if (errno == E2BIG) {
/*
* Lack of space in output buffer
*/
/*
* Outputs converted characters
*/
(void) fwrite(to, 1, BUFSIZ - oleft, stdout);
/*
* Tries to convert remaining characters in
* input buffer with emptied output buffer
*/
continue;
} else if (errno == EILSEQ) {
/*
* Illegal character or shift sequence
*/
/*
* Outputs converted characters
*/
(void) fwrite(to, 1, BUFSIZ - oleft, stdout);
/*
* Initializes the conversion descriptor and
* outputs the sequence to change the state to
* initial state.
*/
INIT_SHIFT_STATE(cd, fptr, ileft, tptr, oleft);
(void) iconv_close(cd);
(void) fprintf(stderr,
"Illegal character or sequence\\n");
return (1);
} else if (errno == EBADF) {
/*
* Invalid conversion descriptor.
* Actually, this hud''''t happen here.
*/
(void) fprintf(stderr, "Conversion error\\n");
return (1);
} else {
/*
* This errno is not defined
*/
(void) fprintf(stderr, "iconv error\\n");
return (1);
}
}
}
/*
* Initializes the conversion descriptor and outputs
* the sequence to change the state to initial state.
*/
INIT_SHIFT_STATE(cd, fptr, ileft, tptr, oleft);
(void) iconv_close(cd);
return (0);
}[/code:1:546c0e288d]
|
|