2

我有一个使用 Microsoft 报告工具创建的文本文件。文本文件BOM 0xFFFE在开头包含 ,然后ASCII在字符之间包含空值(即“ F.i.e.l.d.1.”)的字符输出。我可以iconv用来将其转换为UTF-8用作UCS-2LE输入格式和UTF-8输出格式……效果很好。

我的问题是我想将文件中的行读UCS-2LE入字符串并解析出字段值,然后将它们写入ASCII文本文件(即Field1 Field2)。我已经尝试过基于string和-wstring的版本getline——当它从文件中读取字符串时,类似的函数substr(start, length)会将字符串解释为8-bit值,因此起始值和长度值是关闭的。

如何将UCS-2LE数据读入C++字符串并提取数据值?我查看了boost以及icu无数的谷歌搜索,但没有找到任何有效的东西。我在这里想念什么?请帮忙!

我的示例代码如下所示:

wifstream srcFile;
srcFile.open(argv[1], ios_base::in | ios_base::binary);
..
..
wstring  srcBuf;
..
..
while( getline(srcFile, srcBuf) )
{
    wstring field1;
    field1 = srcBuf.substr(12, 12);
    ...
    ...
}

因此,例如,如果srcBuf包含“ W.e. t.h.i.n.k. i.n. g.e.n.e.r.a.l.i.t.i.e.s.”,那么substr()上面的返回“ .k. i.n. g.e”而不是“ g.e.n.e.r.a.l.i.t.i.e.s.”。

我想要的是读取字符串并处理它,而不必担心多字节表示。是否有人有使用boost(或其他)从文件中读取这些字符串并将它们转换为固定宽度表示以供内部使用的示例?

顺便说一句,我在使用 Eclipse 和 gcc 的 Mac 上。我可能STL不理解宽字符串吗?

谢谢!

4

2 回答 2

1

花了一些时间来解决这个问题,这是我的结论:

  • 在 C++11 中读取UTF-16(或UCS2-LE)文件显然是可管理的,请参阅How do I write a UTF-8 encoded string to a file in Windows, in C++

  • 由于该boost::locale库现在是 C++11 的一部分,因此可以直接使用codecvt_utf16(有关最终代码示例,请参见下面的项目符号)

  • 但是,在较旧的编译器(例如 MSVC 2008)中,您可以使用locale自定义构面/“配方”,这在以二进制模式写入 UTF16 到文件的答案codecvt很好地举例说明

  • 或者,也可以尝试这种阅读方法,尽管在我的情况下它不起作用。输出将丢失被垃圾字符替换的行。

我无法在我的 C++11 之前的编译器中完成这项工作,不得不求助于在 Ruby 中编写脚本并生成一个进程(它只是在测试中,所以我认为这种复杂性是可以的)来执行我的任务。

希望这可以节省其他人一些时间,乐于提供帮助。

于 2013-03-13T12:23:04.920 回答
0

substr 在带有 g++ 4.3.3 的 Linux 上对我来说很好用。该程序

#include <string>
#include <iostream>

using namespace std;

int main()
{
  wstring s1 = L"Hello, world";
  wstring s2 = s1.substr(3,5);
  wcout << s2 << endl;
}

按应有的方式打印“lo,w”。

但是,文件读取可能与您期望的有所不同。它将文件从语言环境编码转换为 wchar_t,这将导致每个字节成为自己的 wchar_t。我认为标准库不支持将 UTF-16 读入 wchar_t。

于 2009-08-09T05:54:02.763 回答