Buffer de salida vacío en iconv, mientras se realiza la conversión de ISO-8859-1 a UTF-8.
En Linux, he creado un archivo con caracteres turcos y cambié el conjunto de caracteres del archivo a “ISO-8859-9”. Con el siguiente código en CPP, intento convertirlo a UTF-8. Pero iconv devuelve un buffer de salida vacío. Sin embargo, “iconv” devuelve “inbytesleft” como “0”, lo que significa que la conversión se realizó en la entrada. ¿Cuál podría ser el error aquí?
Mi formato de archivo en Linux:
[root@osst212 cod]# file test.txt
test.txt: texto ISO-8859
[root@osst212 cod]# cat test.txt –> Aquí mi configuración de caracteres en Putty es ISO-8859-9
fıstıkçı şahap
#include <string>
#include <iostream>
#include <locale>
#include <cstdlib>
#include <fstream>
#include <string>
#include <sstream>
#include <iconv.h>
#include <cstring>
#include <cerrno>
#include <csignal>
using namespace std;
int main()
{
const char* lna = getenv("LANG");
cout << "LANG es " << lna << endl;
setlocale(LC_ALL, "tr_TR.ISO8859-9");
ifstream fsl("test.txt", ios::in);
string myString;
if (fsl.is_open()) {
getline(fsl, myString);
}
size_t ret;
size_t inby = sizeof(myString); // inbytesleft para iconv
size_t outby = 2 * inby; // outbytesleft para iconv
char* input = new char[myString.length() + 1]; // buffer de entrada para ser traducido a UTF-8
strcpy(input, myString.c_str());
char* output = (char*)calloc(outby, sizeof(char)); // buffer de salida
iconv_t iconvcr = iconv_open("UTF-8", "ISO−8859-9");
if ((ret = iconv(iconvcr, &input, &inby, &output, &outby)) == (size_t)-1) {
fprintf(stderr, "No se puede convertir a UTF-8 y el detalle del error es \n", strerror(errno));
}
cout << output << endl;
raise(SIGINT);
iconv_close(iconvcr);
}
Las variables locales después de llamar a iconv son las siguientes, cuando lo ejecuto en gdb. Se puede ver que la salida está vacía.
(gdb) bt
</iconv.h>
0 0x00007ffff7224387 en raise () from /lib64/libc.so.6
1 0x0000000000401155 in main () at stack.cpp:41
(gdb) frame 1
1 0x0000000000401155 in main () at stack.cpp:41
(gdb) info locals
lna = 0x7fffffffef72 "en_US.UTF-8"
fsl = <tipo incompleto="">
ret = 0
inby = 0
outby = 4
myString = "fıstıkçı şahap"
input = 0x606268 " şahap"
output = 0x60628c ""
iconvcr = 0x606a00
davy.ai
El error en el código es que la variable
inby
se inicializa incorrectamente. La funciónsizeof
devuelve el tamaño del objeto en bytes, que en este caso es el tamaño del objetostring
, no el tamaño de su contenido. Por lo tanto, cuando se usainby
como parámetroinbytesleft
eniconv
, es demasiado grande y esto hace queiconv
piense que no hay más entrada para convertir, aunque sí la hay.Para solucionar esto, el código debe usar la función
length
del objetostring
para establecer el valor correcto parainby
:c++
size_t inby = myString.length(); /* inbytesleft para iconv */
Con este cambio,
iconv
debería poder convertir la cadena de entrada a UTF-8 correctamente.