为何iconv转换不成功呢?
下面的程序从GB2312转换到UTF-8. ibuf里面存放的是 "品 "的GB2312编码,
obuf里面存放将要转换的UTF-8编码,但最后obuf里面内容不正确,
不知道问题出在什么地方? 请指点一下!
#include "stdio.h "
#include "unistd.h "
#include "fcntl.h "
#include "iconv.h "
#include "string.h "
#define BUFLEN 20
int main()
{
iconv_t cd;
char obuf[BUFLEN];
char* pobuf = obuf;
char ibuf[BUFLEN] = {0xc6, 0xb7, 0x00};
char* pibuf = ibuf;
size_t ilen,olen,ret;
const char* from_code = "gb2312 ";
const char* to_code = "utf-8 ";
ilen = strlen(ibuf);
olen = BUFLEN;
printf( "\n ");
if ((cd=iconv_open(to_code, from_code)) == (iconv_t)-1)
{
printf( "failed to conv GB2312 to UTF-8\n ");
exit(-1);
}
if (iconv(cd, &pibuf, &ilen, &pobuf, &olen) == (size_t)-1)
{
printf( "failed to conv buf\n ");
exit(-1);
}
printf( "pobuf = %s\n ", pobuf);
printf( "pobuf[0] = %x, pobuf[1] = %x, pobuf[2] = %x\n ", pobuf[0], pobuf[1], pobuf[2]);
iconv_close(cd);
return 0;
}
[解决办法]
源代码在这里:http://code.google.com/p/libkf701/ 一起写来吧
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <iconv.h>
#include <limits.h>
#ifndef SIZE_MAX
# define SIZE_MAX ((size_t) -1)
#endif
/**
* @brief codeset convert
*
* Convert a zero-terminated string STR from the FROM_CODSET code set
* to the TO_CODESET code set. The returned string is allocated using
* malloc, and must be dellocated by the caller using free. On
* failure, NULL is returned and errno holds the error reason. Note
* that if TO_CODESET uses 0 for anything but to terminate the
* string, the caller of this function may have difficulties finding
* out the length of the output string.
*
* @param str raw buffer need convert
* @param from_codeset such as "gbk "
* @param to_codeset such as "utf-8 "
*
* @return the converted buffer or NULL when faild
* you must free the retval buffer yourself
*
*/
char *iconv_string (const char *str, const char *from_codeset,
const char *to_codeset)
{
char *dest = NULL;
iconv_t cd;
char *outp;
char *p = (char *) str;
size_t inbytes_remaining = strlen (p);
/* Guess the maximum length the output string can have. */
size_t outbuf_size = inbytes_remaining + 1;
size_t outbytes_remaining;
size_t err;
int have_error = 0;
/* Use a worst-case output size guess, so long as that wouldn 't be
too large for comfort. It 's OK if the guess is wrong so long as
it 's nonzero. */
size_t approx_sqrt_SIZE_MAX = SIZE_MAX > > (sizeof (size_t) * CHAR_BIT / 2);
if (outbuf_size <= approx_sqrt_SIZE_MAX / MB_LEN_MAX)
outbuf_size *= MB_LEN_MAX;
outbytes_remaining = outbuf_size - 1;
if (strcmp (to_codeset, from_codeset) == 0)
return strdup (str);
cd = iconv_open (to_codeset, from_codeset);
if (cd == (iconv_t) -1)
return NULL;
outp = dest = (char *) malloc (outbuf_size);
if (dest == NULL)
goto out;
again:
err = iconv (cd, &p, &inbytes_remaining, &outp, &outbytes_remaining);
if (err == (size_t) - 1)
{
switch (errno)
{
case EINVAL:
/* Incomplete text, do not report an error */
break;
case E2BIG:
{
size_t used = outp - dest;
size_t newsize = outbuf_size * 2;
char *newdest;
if (newsize <= outbuf_size)
{
errno = ENOMEM;
have_error = 1;
goto out;
}
newdest = (char *) realloc (dest, newsize);
if (newdest == NULL)
{
have_error = 1;
goto out;
}
dest = newdest;
outbuf_size = newsize;
outp = dest + used;
outbytes_remaining = outbuf_size - used - 1; /* -1 for NUL */
goto again;
}
break;
case EILSEQ:
have_error = 1;
break;
default:
have_error = 1;
break;
}
}
*outp = '\0 ';
out:
{
int save_errno = errno;
if (iconv_close (cd) < 0 && !have_error)
{
/* If we didn 't have a real error before, make sure we restore
the iconv_close error below. */
save_errno = errno;
have_error = 1;
}
if (have_error && dest)
{
free (dest);
dest = NULL;
errno = save_errno;
}
}
return dest;
}
[解决办法]
http://libkf701.googlecode.com/svn/trunk/lib/iconvme.c
都写好了,收集车轮子