Разбор текстового файла UCS-2LE - PullRequest
2 голосов
/ 08 августа 2009

У меня есть текстовый файл, созданный с помощью какого-либо инструмента отчетности Microsoft. Текстовый файл включает в себя BOM 0xFFFE в начале, а затем ASCII символьный вывод с нулями между символами (т. Е. "F.i.e.l.d.1."). Я могу использовать iconv, чтобы преобразовать это в UTF-8, используя UCS-2LE в качестве формата ввода и UTF-8 в качестве формата вывода ... это прекрасно работает.

Моя проблема в том, что я хочу прочитать строки из файла UCS-2LE в строки и разобрать значения полей, а затем записать их в текстовый файл ASCII (т.е. Field1 Field2). Я пробовал версии getline на основе string и wstring - пока он читает строку из файла, такие функции, как substr(start, length), интерпретируют строку как значения 8-bit, поэтому значения начала и длины выкл.

Как прочитать данные UCS-2LE в строку C++ и извлечь значения данных? Я просмотрел boost и icu, а также многочисленные поиски в Google, но не нашел ничего, что работает. Что мне здесь не хватает? Пожалуйста, помогите!

Мой пример кода выглядит так:

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 (или что-то еще) для чтения этих строк из файла и преобразования их в представление с фиксированной шириной для внутреннего использования?

Кстати, я на Mac использую Eclipse и gcc .. Возможно ли, что мой STL не понимает строки широких символов?

Спасибо!

Ответы [ 2 ]

1 голос
/ 13 марта 2013

Потратив несколько часов на решение этого вопроса, вот мои выводы:

  • Чтение файла UTF-16 (или UCS2-LE), по-видимому, управляемо в C ++ 11, см. Как записать кодированную строку UTF-8 в файл в Windows, в C ++

  • Поскольку библиотека boost::locale теперь является частью C ++ 11, можно просто использовать codecvt_utf16 (возможные примеры кода см. Ниже),

  • Однако в старых компиляторах (например, MSVC 2008) вы можете использовать locale и пользовательский codecvt facet / "recipe", что очень хорошо иллюстрируется в этом ответе to Запись UTF16 в файл в двоичном режиме

  • В качестве альтернативы можно попробовать этот метод чтения, хотя в моем случае это не сработало. В результате будут отсутствовать строки, которые были заменены символами мусора.

Мне не удалось это сделать в моем компиляторе до C ++ 11, и мне пришлось прибегнуть к написанию сценариев в Ruby и запустить процесс (это только в тесте, так что я думаю, что здесь есть какие-то сложности) выполнить мою задачу.

Надеюсь, это когда-нибудь пощадит других, с радостью помогу.

0 голосов
/ 09 августа 2009

substr прекрасно работает на Linux с g ++ 4.3.3. Программа

#include <string>
#include <iostream>

using namespace std;

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

печатает "вот так", как и должно.

Однако чтение файла, вероятно, делает что-то отличное от того, что вы ожидаете. Он преобразует файлы из кодировки локали в wchar_t, в результате чего каждый байт становится своим собственным wchar_t. Я не думаю, что стандартная библиотека поддерживает чтение UTF-16 в wchar_t.

...