Iconv only works once

I am trying to make a method that converts an s-jis string to a utf-8 string using iconv. I wrote the code below

#include <iconv.h>
#include <iostream>
#include <stdio.h>
using namespace std;

#define BUF_SIZE 1024
size_t z = (size_t) BUF_SIZE-1;

bool sjis2utf8( char* text_sjis, char* text_utf8 )
{
  iconv_t ic;
  ic = iconv_open("UTF8", "SJIS"); // sjis->utf8
  iconv(ic , &text_sjis, &z, &text_utf8, &z);
  iconv_close(ic);
  return true;
}
int main(void)
{
  char hello[BUF_SIZE] = "hello";
  char bye[BUF_SIZE] = "bye";
  char tmp[BUF_SIZE] = "something else";

  sjis2utf8(hello, tmp);
  cout << tmp << endl;

  sjis2utf8(bye, tmp);
  cout << tmp << endl;
}

and, the conclusion should be

hello
bye

but actually,

hello
hello

Does anyone know why this phenomenon occurs? What happened to my program?

Note that "hello" and "bye" are Japanese s-jis strings in my original program, but I changed it to make it easier to view the program.

+3
source share
4 answers

, iconv, z. sjis2utf8, z 0. sjis2utf8 (z == 0) tmp .

iconv documentation:

size_t iconv (iconv_t cd,
              const char* * inbuf, size_t * inbytesleft,
              char* * outbuf, size_t * outbytesleft);

iconv , * inbuf * inbytesleft , * outbuf * outbytesleft , , cd.

:

size_t il = BUF_SIZE - 1 ;
size_t ol = BUF_SIZE - 1 ;

iconv(ic, &text_sjis, &il, &text_utf8, &ol) ;

iconv .

+3
#include <iconv.h>
#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

const size_t BUF_SIZE=1024;


class IConv {
    iconv_t ic_;
public:
    IConv(const char* to, const char* from) 
        : ic_(iconv_open(to,from))    { }
    ~IConv() { iconv_close(ic_); }

     bool convert(char* input, char* output, size_t& out_size) {
        size_t inbufsize = strlen(input)+1;// s-jis string should be null terminated, 
                                           // if s-jis is not null terminated or it has
                                           // multiple byte chars with null in them this
                                           // will not work, or to provide in other way
                                           // input buffer length....
        return iconv(ic_, &input, &inbufsize, &output, &out_size);
     }
};

int main(void)
{
    char hello[BUF_SIZE] = "hello";
    char bye[BUF_SIZE] = "bye";
    char tmp[BUF_SIZE] = "something else";
    IConv ic("UTF8","SJIS");

    size_t outsize = BUF_SIZE;//you will need it
    ic.convert(hello, tmp, outsize);
    cout << tmp << endl;

    outsize = BUF_SIZE;
    ic.convert(bye, tmp, outsize);
    cout << tmp << endl;
}
  • Kleist
+1

iconv.

Try:

//...
int len = strlen(text_sjis);
iconv(ic , &text_sjis, &len, &text_utf8, &z);
//...
0
size_t iconv (iconv_t cd,
          const char* * inbuf, size_t * inbytesleft,
          char* * outbuf, size_t * outbytesleft);

iconv , inbytesleft. z 0. , inbuf .

: http://www.gnu.org/s/libiconv/documentation/libiconv/iconv.3.html

++, , , inconv_t, iconv_open, , d.

#include <iconv.h>
#include <iostream>
#include <stdio.h>
#include <string.h>

using namespace std;

const size_t BUF_SIZE = 1024;
size_t z = (size_t) BUF_SIZE-1;

class IConv {
    iconv_t ic_;
public:
    IConv(const char* to, const char* from) 
        : ic_(iconv_open(to,from))    { }

    ~IConv() { iconv_close(ic_); }

    bool convert(char* input, char* output, size_t outbufsize) {
        size_t inbufsize = strlen(input);
        return iconv(ic_, &input, &inbufsize, &output, &outbufsize);
    }
};

int main(void)
{
    char hello[BUF_SIZE] = "hello";
    char bye[BUF_SIZE] = "bye";
    char tmp[BUF_SIZE] = "something else";
    IConv ic("UTF8","SJIS");


    ic.convert(hello, tmp, BUF_SIZE);
    cout << tmp << endl;

    ic.convert(bye, tmp, BUF_SIZE);
    cout << tmp << endl;
}
0
source

Source: https://habr.com/ru/post/1665491/


All Articles