iconv 中的输出缓冲区为空,同时从 ISO-8859-1 转换为 UTF-8

Posted

技术标签:

【中文标题】iconv 中的输出缓冲区为空,同时从 ISO-8859-1 转换为 UTF-8【英文标题】:Output buffer empty in iconv , while converting from ISO-8859-1 to UTF-8 【发布时间】:2022-01-16 10:16:11 【问题描述】:

在 linux 中,我创建了一个带有土耳其语字符的文件,并将文件字符集更改为“ISO-8859-9”。使用以下 cpp,我正在尝试将其转换为 UTF-8。但是 iconv 返回空的输出缓冲区。但是“iconv”返回“inbytesleft”,因为“0”表示在输入上完成转换。这里可能是什么错误?

我的linux文件格式: [root@osst212 cod]#文件test.txt test.txt:ISO-8859 文本

[root@osst212 cod]# cat test.txt --> 这里我的putty字符集设置是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 is " << 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 for iconv */
size_t outby = 2 * inby;                          /*outbytesleft for iconv*/

char* input = new char [myString.length()+1];     /* input buffer to be translated to UTF-8 */
strcpy(input,myString.c_str());
char* output = (char*) calloc(outby,sizeof(char)); /* output buffer */

iconv_t iconvcr = iconv_open("UTF-8", "ISO−8859-9");
if ((ret = iconv(iconvcr,&input,&inby,&output,&outby)) == (size_t) -1) 
        fprintf(stderr,"Could not convert to UTF-8 and error detail is \n",strerror(errno)); 

cout << output << endl;
raise(SIGINT);
iconv_close(iconvcr);


iconv 调用后的局部变量如下,当我在 gdb 下运行它时。可以看到输出为空。

(gdb) bt
#0  0x00007ffff7224387 in 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
41      raise(SIGINT);
(gdb) info locals
lna = 0x7fffffffef72 "en_US.UTF-8"
fsl = <incomplete type>
ret = 0
inby = 0
outby = 4
myString = "f\375st\375k\347\375 \376ahap"
input = 0x606268 " \376ahap"
output = 0x60628c ""
iconvcr = 0x606a00

【问题讨论】:

现在,看看调用iconv之前的所有值是什么,看看所有这些值是不是你认为的,问题应该是相当明显的。您还应该弄清楚代码中的哪一行可以确保以 output 结尾的任何内容都正确地以 '\0' 终止,以便 &lt;&lt; 运算符对于纯字符指针正常工作(但这只是一个额外的问题) . 【参考方案1】:

男人 3 图标v

iconv() 函数一次转换一个多字节字符,对于每个字符转换,它递增 *inbuf 并递减 *inbytesleft 转换的输入字节数,递增 *outbuf 并递减 @ 987654325@按转换后的输出字节数

output 更新为指向最初分配的缓冲区中下一个未使用的字节。

正确的用法

char* nextouput = output:
if ((ret = iconv(iconvcr, &input, &inby, &nextoutput, &outby)) == (size_t) -1) 
    fprintf(stderr, "Could not convert to UTF-8 and error detail is \n", strerror(errno)); 

【讨论】:

非常感谢,是的,已修复。我还更正了“size_t inby = myString.length();”变量声明。

以上是关于iconv 中的输出缓冲区为空,同时从 ISO-8859-1 转换为 UTF-8的主要内容,如果未能解决你的问题,请参考以下文章

iconv“缓冲区末尾的字符或移位序列不完整”错误

iconv

linux常用命令:iconv 命令

Linux打开设备时串口缓冲区不为空

生产消费模式

linux之iconv命令