我有一个使用某些Microsoft报告工具创建的文本文件。文本文件在开头包含BOM
0xFFFE
,然后在ASCII
字符输出中包含字符之间的空值(即“F.i.e.l.d.1.
”)。我可以使用iconv
将此转换为UTF-8
,使用UCS-2LE
作为输入格式,UTF-8
作为输出格式......效果很好。
我的问题是,我希望从UCS-2LE
文件中读取字符串并解析字段值,然后将其写入ASCII
文本文件(即Field1 Field2
)。我尝试了基于string
和wstring
的{{1}}版本 - 当它从文件中读取字符串时,像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.
(或其他东西)从文件中读取这些字符串并将它们转换为固定宽度表示以供内部使用?
顺便说一下,我在Mac上使用Eclipse和gcc ..我的boost
是否可能无法理解宽字符串?
谢谢!
答案 0 :(得分: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
和自定义codecvt
构面/“配方”,在this answer中非常好地举例说明Writing UTF16 to file in binary mode
或者,也可以尝试this method阅读,但在我的情况下它不起作用。输出将丢失被垃圾字符替换的行。
我无法在我的C ++ 11之前的编译器中完成这项工作,不得不求助于在Ruby中编写脚本并生成一个进程(它只是在测试中,所以我认为那种复杂性是可行的)执行我的任务。
希望这能让其他人节省一些时间,很乐意提供帮助。
答案 1 :(得分:0)
substr对我来说很好。该计划
#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。