Unicode gtkmm中是否有一个函数可以从FileInputStream中读取数据,然后使用该函数设置TextArea
我正在尝试从文件中读取文本并将其放在文本视图中。有Unicode gtkmm中是否有一个函数可以从FileInputStream中读取数据,然后使用该函数设置TextArea,unicode,gtkmm,Unicode,Gtkmm,我正在尝试从文件中读取文本并将其放在文本视图中。有read_bytes,有set_text,可以执行ustring,但似乎没有办法从一个转到另一个 在InputStream的子类中,我发现它确实有read\u line\u utf8提供一个std::string(总比没有好),但即使是DataInputStream也位于与FileInputStream分离的类层次结构分支上 当然,从理论上讲,可以循环读取字节返回的字节数组,并将它们转换为字符,但不知何故,我拒绝相信没有我忽略的现成函数 最终,我
read_bytes
,有set_text
,可以执行ustring
,但似乎没有办法从一个转到另一个
在InputStream的子类中,我发现它确实有read\u line\u utf8
提供一个std::string(总比没有好),但即使是DataInputStream也位于与FileInputStream分离的类层次结构分支上
当然,从理论上讲,可以循环读取字节返回的字节数组,并将它们转换为字符,但不知何故,我拒绝相信没有我忽略的现成函数
最终,我正在寻找一个函数,它将接受
Glib::RefPtr
,并返回一个Glib::ustring
OK,在广泛搜索之后,我已设法确认在gtkmm库的范围内没有这样做的方法。这对我来说确实很奇怪,但确实如此
下面是如何通过普通工具读取文件,然后转换您读取的内容,并将其显示在文本区域:
我假设您已经打开了对话框,并连接了所有需要连接的内容。如果您有一个控制器类,那么最终将得到以下内容:
fh = dialog->get_file();
fh->read_async( sigc::mem_fun( *this, &Controller::on_file_read_complete ));
确保你有Glib::RefPtrfh
作为私有数据成员,而不是局部变量。然后,您将需要一个函数来读取文件\u read\u complete
void Controller::on_file_read_complete(Glib::RefPtr<Gio::AsyncResult>& res)
{
Glib::RefPtr<Gio::InputStream> fin = fh->read_finish(res);
Glib::RefPtr<Glib::Bytes> fbytes = fin->read_bytes(8192, Glib::RefPtr<Gio::Cancellable>());
Glib::ustring str = bytesToUstring(fbytes);
Gtk::TextView *textview = NULL;
refGlade->get_widget("textviewUser", textview);
assert(textview!=NULL);
textview->get_buffer()->set_text(str);
}
在这里,我们必须首先抓住字节的真正指针,因为Glib::bytes
将拒绝为您提供所需的工具。然后您可以开始转换为wchar\t
。这个过程并没有那么困难,在本文中描述得足够好
幸运的是,wchar\u t
可以转换为gunichar
,而这反过来又可以添加到Glib::ustring
因此,我们必须走的道路是:
Dialog->Gio::File->Glib::Bytes->gconstpointer->char->(组合多个字符)wchar\u t->gunichar->Glib::ustring->(添加到TextArea的TextBuffer)
注:目前这不是一个现成的代码,它只读取8192个字节,它不能帮助读更多,因为不能保证字符在两次读取中间没有被破解,也许我稍后会更新代码。
Glib::ustring bytesToUstring(Glib::RefPtr<Glib::Bytes> data)
{
Glib::ustring result = "";
gsize s;
gconstpointer d = g_bytes_get_data(data->gobj(), &s);
unsigned char c;
wchar_t wc;
unsigned short toread = 0;
for(int i=0; i<(int)s; ++i)
{
c = ((char*)d)[i];
if((c >> 7) == 0b0)
{
//std::cout << "Byte 0b0" << std::endl;
if(toread!=0)
{
std::cerr << "Help. I lost my place in the stream" << std::endl;
}
wc = (wchar_t)c;
}
else if((c >> 6) == 0b10)
{
//std::cout << "Byte 0b10" << std::endl;
if(toread==0)
{
std::cerr << "Help. I lost my place in the stream" << std::endl;
}
wc <<= 6; // 6 more bits are coming in
wc |= (c & 0b00111111);
--toread;
}
else // we can be sure that we have something starting with at least 2 set bits
{
if(toread!=0)
{
std::cerr << "Help. I lost my place in the stream" << std::endl;
}
if((c >> 5) == 0b110)
{
//std::cout << "Byte 0b110" << std::endl;
wc = c & 0b00011111;
toread = 1;
}
else if((c >> 4) == 0b1110)
{
//std::cout << "Byte 0b1110" << std::endl;
wc = c & 0b00001111;
toread = 2;
}
else if((c >> 3) == 0b11110)
{
//std::cout << "Byte 0b11110" << std::endl;
wc = c & 0b00000111;
toread = 3;
}
else if((c >> 2) == 0b111110)
{
//std::cout << "Byte 0b111110" << std::endl;
wc = c & 0b00000011;
toread = 4;
}
else if((c >> 1) == 0b1111110)
{
//std::cout << "Byte 0b1111110" << std::endl;
wc = c & 0b00000001;
toread = 5;
}
else // wtf?
{
std::cerr << "Help! Something is probaby not a UTF-8 at all" << std::endl;
for(int j=(8*(int)sizeof c) - 1; j>=0; --j)
{
std::cerr << (char)('0'+ (char)((c >> j) & 1));
}
std::cerr << std::endl;
}
}
if(toread == 0)
{
result += (gunichar)wc;
wc = L'\0';
//std::cout << i << ' ' << result << std::endl;
}
}
return result;
}