头文件:
常用函数:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/* Identifier for conversion method from one codeset to another. */
typedefvoid *iconv_t;
/* Allocate descriptor for code conversion from codeset FROMCODE to
codeset TOCODE.
This function is a possible cancellation points and therefore not
marked with __THROW. */
externiconv_ticonv_open (__constchar *__tocode, __constchar *__fromcode);
/* Convert at most *INBYTESLEFT bytes from *INBUF according to the
code conversion algorithm specified by CD and place up to
*OUTBYTESLEFT bytes in buffer at *OUTBUF. */
externsize_ticonv (iconv_t __cd,
char
**__restrict __inbuf,
size_t
*__restrict __inbytesleft,
char
**__restrict __outbuf,
size_t
*__restrict __outbytesleft);
/* Free resources allocated for descriptor CD for code conversion.
This function is a possible cancellation points and therefore not
marked with __THROW. */
externinticonv_close (iconv_t __cd);
|
注意事项
:
1)outlen和inlen的长度最好相等,iconv会转换所有outlen长度的内容,如果inlen长度不够,可能会造成访问越界的问题。
2)当ASCII转到GBK时,ASCII字符占一位,中文等的书字符占两位;
3)当ASCII转到UTF16BE时,ASCII字符占两位,前补零,所以UTF16BE格式不能用strlen取长度或用%s的printf。
遗留问题:
【原因】size_t在64位系统上是8字节,而在32位系统上是4字节,int为4字节。这样导致取地址的时候越界。
size_t定义如下:
1
2
3
4
5
6
7
|
#ifndef __SIZE_TYPE__
#define __SIZE_TYPE__ long unsigned int
#endif
#if !(defined (__GNUG__) && defined (size_t))
typedef
__SIZE_TYPE__
size_t
;
#ifdef __BEOS__
typedef
long
ssize_t;
|
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <iconv.h>
#include <errno.h>
#define MIN(a,b) ((a)>(b)?(b):(a))
void
dumprawmsg(
char
*p,
int
len)
{
int
i = 0;
for
(i = 0; i < len; i++)
{
unsigned
char
c = p[i];
printf
(
"%.2X "
, c);
}
printf
(
"\n"
);
}
int
convmsg(
char
* src,
char
* des,
int
srclen,
int
deslen,
const
char
*srctype,
const
char
*destype)
{
if
(
strcmp
(srctype, destype) == 0)
{
memcpy
(des, src, MIN(srclen, deslen));
return
0;
}
iconv_t conv = iconv_open (destype, srctype);
if
(conv == (iconv_t)-1)
{
printf
(
"iconvopen err\n"
);
return
-1;
}
char
*in = src;
char
*out = des;
// int ret = iconv (conv, &in, (size_t *) & srclen,
// &out,
// (size_t *)& deslen);
//
// if(ret == 0)
// {
// printf ("iconv succ\n");
// }
// else
// {
// if(errno == 84)
// {
// printf("iconv 84:%d,%d\n", srclen, deslen);
// }
// else
// {
// printf("iconv err %d:%d,%d\n", errno, srclen, deslen);
// }
// }
size_t
avail = deslen;
size_t
insize = srclen;
char
*wrptr = des;
char
*inptr = src;
while
(avail > 0)
{
size_t
nread;
size_t
nconv;
printf
(
"avail:%d\n"
, avail);
/* Do the conversion. */
nconv = iconv (conv, &inptr, &insize, &wrptr, &avail);
if
(nconv == (
size_t
) -1)
{
/* Not everything went right. It might only be
an unfinished byte sequence at the end of the
buffer. Or it is a real problem. */
if
(
errno
== EINVAL)
{
/* This is harmless. Simply move the unused
bytes to the beginning of the buffer so that
they can be used in the next round. */
//memmove (inbuf, inptr, insize);
printf
(
"EINVAL\n"
);
}
else
{
/* It is a real problem. Maybe we ran out of
space in the output buffer or we have invalid
input. In any case back the file pointer to
the position of the last processed byte. */
printf
(
"error\n"
);
break
;
}
}
}
iconv_close (conv);
return
0;
}
int
main(
int
argc,
char
* argv[])
{
if
(argc < 3)
{
printf
(
"need two type para\n"
);
return
-1;
}
printf
(
"type in %s\n, type out %s\n"
, argv[1], argv[2]);
char
src[100] =
"abcd 1234 其他"
;
char
des[100] = {0};
int
srclen = 50;
int
deslen = 50;
const
char
* srctype = argv[1];
const
char
* destype = argv[2];
dumprawmsg(des, 400);
int
ret = convmsg(src, des, srclen, deslen, srctype, destype);
dumprawmsg(des, 400);
printf
(
"des is : %s\n"
, des);
return
0;
}
|