В Linux я использую библиотеку iconv
(ссылка) , которая очень стандартна. Чрезмерно простая программа:
#include <stdio.h>
#include <stdlib.h>
#include <iconv.h>
#define BUF_SZ 1024
int main( int argc, char* argv[] )
{
char bin[BUF_SZ];
char bout[BUF_SZ];
char* inp;
char* outp;
ssize_t bytes_in;
size_t bytes_out;
size_t conv_res;
if( argc != 3 )
{
fprintf( stderr, "usage: convert from to\n" );
return 1;
}
iconv_t conv = iconv_open( argv[2], argv[1] );
if( conv == (iconv_t)(-1) )
{
fprintf( stderr, "Cannot conver from %s to %s\n", argv[1], argv[2] );
return 1;
}
bytes_in = read( 0, bin, BUF_SZ );
{
bytes_out = BUF_SZ;
inp = bin;
outp = bout;
conv_res = iconv( conv, &inp, &bytes_in, &outp, &bytes_out );
if( conv_res >= 0 )
{
write( 1, bout, (size_t)(BUF_SZ) - bytes_out );
}
}
iconv_close( conv );
return 0;
}
Это слишком просто, чтобы продемонстрировать конверсию. В реальном мире у вас обычно есть два вложенных цикла:
- Один вход для чтения, поэтому обрабатывайте, когда его больше, чем BUF_SZ
- Одно преобразование ввода в вывод. Помните, что если вы конвертируете из ascii в UTF-32LE, то в конечном итоге каждый байт iunput будет иметь 4 байта вывода. Таким образом, внутренний цикл будет обрабатывать это, проверяя
conv_res
, а затем проверяя errno
.