1 / 1 / 2
Регистрация: 03.04.2013
Сообщений: 48
1

Подскажите с кодировкой файла в UCS-2

15.05.2016, 00:37. Показов 3584. Ответов 14
Метки нет (Все метки)

Всем привет.
Не получается получить на выходе файл в кодировке UCS-2 LE BOM. (из win-1251)
Пробую так:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include <iostream>
#include <string>
#include <windows.h>
#include <fstream>
#include <cstdlib>
#include <iomanip>
#include <vector>
#include <sstream>
 
using namespace std;
 
 
int StrToWStr(std::wstring &dest, const std::string &source, UINT ResultCodePage = CP_ACP, DWORD dwFlags = 0)
    {
        dest.resize(source.length() +1);
        return MultiByteToWideChar(ResultCodePage, dwFlags, source.c_str(), source.length(), (WCHAR*)dest.c_str(), source.length() + 1);
    }
 
int WStrToStr(std::string &dest, const std::wstring &source, UINT ResultCodePage = CP_ACP, DWORD dwFlags = 0)
    {
        int dest_len = WideCharToMultiByte(ResultCodePage, dwFlags, source.c_str(), source.length(), (LPSTR)dest.c_str(), 0, NULL, NULL);
        dest.resize(dest_len);
        WideCharToMultiByte(ResultCodePage, dwFlags, source.c_str(), source.length(), (LPSTR)dest.c_str(), dest_len, NULL, NULL);
 
        return dest_len;
    }
// конвертирует std::string -> [ResultCodePage] -> std::string
int StrToStr(std::string& dest, const std::string& source, UINT ResultCodePage = CP_ACP, DWORD dwFlags = 0)
{
    std::wstring wstr; StrToWStr(wstr, source);
    return WStrToStr(dest, wstr, ResultCodePage, dwFlags);
}
 
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
 
 
string t = "проверка 12345";
string w;
 
int k = StrToStr(w,t,CP_WINUNICODE,0);
 
string file = "test.qqq";
ofstream fs(file.c_str(), ios::out);
fs << w << endl;
fs.close();
 
 
return 0;
}
Но на выходе идет пустой файл.
В OEM 866 и UTF-8 без проблем, меняю только в функции StrToStr(w,t,CP_OEMCP,0); и StrToStr(w,t,CP_UTF8,0).
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.05.2016, 00:37
Ответы с готовыми решениями:

Перекодировать из UCS-2 Little Endian в UTF
Есть много файлов *.txt в кодировке (как я понял) UCS-2 Little Endian. Как перевести эти файлы в...

Считать текст из файла с кодировкой utf-16 LE
Возникла кое-какая проблема. У меня имеется xml файл, в кодировке UTF-16 LE с определенным...

Из UCS-2 Little Endian в UTF-8 без BOM
Здравствуйте! Имеется файлик xml в кодировке UCS-2 Little Endian. Хочу написать обработчик на...

Проблемы с кодировкой при подключении текстового файла
Проблема вот в чем...В файле question.txt лежит вопрос, написанный по русски, но когда в консоле я...

14
199 / 199 / 78
Регистрация: 10.07.2012
Сообщений: 409
15.05.2016, 08:38 2
Эта кодировка не является "многобайтовой".
Поэтому MultiByte функции её не поддерживают.

Да и смысла в этом мало.
После применения функции StrToWStr как раз тот самый UCS-2 (то есть, UTF-16) и получается.
Остаётся только BOM вручную прицепить.
0
7167 / 6142 / 2802
Регистрация: 14.04.2014
Сообщений: 26,462
15.05.2016, 11:51 3
codecvt всё сам прицепляет.
1
1 / 1 / 2
Регистрация: 03.04.2013
Сообщений: 48
15.05.2016, 12:57  [ТС] 4
Оставил только StrToWStr, добавил BOM в начало файла. Кодировка судя по notepad++ стала верной. Но в файл текст иероглифами идет. Не пойму как правильно wstring который UTF-16 после функции содержит правильно в файл направить.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>
#include <string>
#include <windows.h>
#include <fstream>
#include <cstdlib>
#include <iomanip>
#include <vector>
#include <sstream>
 
using namespace std;
 
 
int StrToWStr(std::wstring &dest, const std::string &source, UINT ResultCodePage = CP_ACP, DWORD dwFlags = 0)
    {
        dest.resize(source.length() +1);
        return MultiByteToWideChar(ResultCodePage, dwFlags, source.c_str(), source.length(), (WCHAR*)dest.c_str(), source.length() + 1);
    }
 
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
string file = "test.qqq";
 
ofstream fs1;
fs1.open(file.c_str(), ios::out|ios::binary);
 
unsigned char smarker[2];//BOM
smarker[0] = 0xFF;
smarker[1] = 0xFE;
 
fs1 << smarker;
fs1.close();
 
 
string t = "проверка 12345";
wstring w;
int k = StrToWStr(w,t);
wofstream fs(file.c_str(), wofstream::app | wofstream::binary);
fs << w << endl;
fs.close();
 
 
return 0;
}
0
199 / 199 / 78
Регистрация: 10.07.2012
Сообщений: 409
15.05.2016, 14:48 5
Цитата Сообщение от kbv025 Посмотреть сообщение
Но в файл текст иероглифами идет. Не пойму как правильно wstring который UTF-16 после функции содержит правильно в файл направить.
можно сделать вот так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
    char smarker[2];//BOM
    smarker[0] = 0xFF;
    smarker[1] = 0xFE;
 
    fs1.write(smarker, 2);
    fs1.close();
 
    string t = "проверка 12345";
    wstring w;
    int k = StrToWStr(w, t);
    ofstream fs(file.c_str(), wofstream::app | wofstream::binary);
    fs.write((char*)w.c_str(), w.length() * 2);
    fs.close();
Но вариант с codecvt, наверное, будет лучше.
1
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
15.05.2016, 15:21 6
ваш исходник в какой кодировке? 1251 или утф8 или где?
0
199 / 199 / 78
Регистрация: 10.07.2012
Сообщений: 409
15.05.2016, 16:14 7
Вот вариант с codecvt:
C++
1
2
3
4
5
6
7
8
9
    string t = "проверка 12345";
    wstring w;
    StrToWStr(w, t);
 
    wstring_convert<codecvt_utf16<
        wchar_t, 0x10ffff, codecvt_mode(generate_header | little_endian)>> conv;
    ofstream fs(file.c_str());
    fs << conv.to_bytes(w);
    fs.close();
Даже не знаю какой из вариантов лучше смотрится.

Цитата Сообщение от retmas Посмотреть сообщение
ваш исходник в какой кодировке? 1251 или утф8 или где?
Во второй строчке первого сообщения написано
0
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
15.05.2016, 16:27 8
C++
1
MultiByteToWideChar(1251, ...);
и еще имя параметра ResultCodePage навивает на мысли, что автор не понял смысла параметра. может я не прав
0
199 / 199 / 78
Регистрация: 10.07.2012
Сообщений: 409
15.05.2016, 16:32 9
Цитата Сообщение от retmas Посмотреть сообщение
и еще имя параметра ResultCodePage навивает на мысли, что автор не понял смысла параметра. может я не прав
там ещё +1 проблемы создаёт
но, в принципе, функция более-менее работает
0
Жарю без масла
867 / 749 / 225
Регистрация: 13.01.2012
Сообщений: 1,702
15.05.2016, 16:34 10
а у меня все же есть сомнения, что исходник программы в ср1251. может все же утф? автору следовало бы проверить
0
1 / 1 / 2
Регистрация: 03.04.2013
Сообщений: 48
15.05.2016, 17:02  [ТС] 11
Я в CodeBloks делаю там пишет, что кодировка кода w1251;
С codecvt чето не разобрался, не пошел у меня код под него. Не мгу правильно прицепить его к CodeBloks. Пишет не найден файл. Так что уж лучше альтернатива, я хоть более менее понимаю ее.
Vort_ твой первый вариант работает как надо. Единственное как в конце стоки убрать признак конца строки NUL (\0)? Программа для которой файл делаю чето упорно игнорит данные если они на него заканчиваются строки.

В общем пока как то так, добавил еще перенос на новую строку. Этот nul победить и будет отлично.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <string>
#include <windows.h>
#include <fstream>
#include <cstdlib>
#include <iomanip>
#include <vector>
#include <sstream>
#include <iostream>
#include <locale>
 
using namespace std;
 
 
int StrToWStr(std::wstring &dest, const std::string &source, UINT ResultCodePage = CP_ACP, DWORD dwFlags = 0)
    {
        dest.resize(source.length() +1);
        return MultiByteToWideChar(ResultCodePage, dwFlags, source.c_str(), source.length(), (WCHAR*)dest.c_str(), source.length() + 1);
    }
 
 
void file_ucs(string stroka)
{
    string file = "test.qqq";
    string t = stroka;
    wstring w;
    int k = StrToWStr(w,t);
    ofstream fs(file.c_str(), wofstream::app | wofstream::binary);
    fs.write((char*)w.c_str(), w.length() * 2);
    fs.write("\n",2);
    fs.close();
 
}
 
 
int main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);
string file = "test.qqq";
ofstream fs1;
fs1.open(file.c_str(), ios::out|ios::binary);
 
char smarker[2];//BOM
    smarker[0] = 0xFF;
    smarker[1] = 0xFE;
 
    fs1.write(smarker, 2);
    fs1.close();
 
 
vector <string> tabl1;
tabl1.resize(3);
 
tabl1[0] = "Задача 1";
tabl1[1] = "Задача 2";
tabl1[2] = "Zadacha 3";
 
 
for (int i=0; i < tabl1.size(); i++)
{
    file_ucs(tabl1[i]);
}
 
return 0;
}
0
199 / 199 / 78
Регистрация: 10.07.2012
Сообщений: 409
15.05.2016, 17:11 12
Цитата Сообщение от kbv025 Посмотреть сообщение
Единственное как в конце стоки убрать признак конца строки NUL (\0)?
Проблема, скорее всего, вот в этой строчке:
C++
1
dest.resize(source.length() +1);
Попробуй убрать +1
1
7167 / 6142 / 2802
Регистрация: 14.04.2014
Сообщений: 26,462
15.05.2016, 17:12 13
Цитата Сообщение от kbv025 Посмотреть сообщение
С codecvt чето не разобрался, не пошел у меня код под него.
<codecvt> подключил? C++11 поддерживается?
0
199 / 199 / 78
Регистрация: 10.07.2012
Сообщений: 409
15.05.2016, 17:20 14
Цитата Сообщение от nmcf Посмотреть сообщение
<codecvt> подключил? C++11 поддерживается?
Я отвечу.

Стандартный компилятор Code::Blocks 16.01 ничего не знает про <codecvt>.
После того как я подцепил к Code::Blocks компилятор из msys2, то всё заработало.
Но нужна ли kbv025 эта морока - вопрос открытый.
0
1 / 1 / 2
Регистрация: 03.04.2013
Сообщений: 48
15.05.2016, 17:25  [ТС] 15
Цитата Сообщение от Vort_ Посмотреть сообщение
Проблема, скорее всего, вот в этой строчке:
C++Выделить код
1
dest.resize(source.length() +1);
Попробуй убрать +1
Спасибо, все отрабатывает нормально. NUL ушел. Файл принимается. Очень помогли.

Добавлено через 4 минуты
Цитата Сообщение от nmcf Посмотреть сообщение
<codecvt> подключил? C++11 поддерживается?
Я подключал так.
C++
1
#include "codecvt/codecvt.h"
, с исходниками файлы добавил в проект.
А <codecvt> - а так нету там такого. И предложенный выше код в ошибку вылетает.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.05.2016, 17:25
Помогаю со студенческими работами здесь

Программа не обрабатывает текст из файла с кодировкой, отличной от ANSI
Здравствуйте. Имеется программка, которая читает текст из файла, обрабатывает его и записывает...

Чтение файла (с кракозябрами) с однобайтовой кодировкой, конвертация в UTF-8 и вывод в другой файл
Добрый день, форумчане. Может у кого есть заготовка или кто поделится советом, необходимо...

Чтение из файла с кодировкой UCS-2 LE BOM
Приветствую. Написал &quot;прогу&quot; которая считывает по символьно текст из файла в массив и выводит...

С кодировкой базы данных и кодировкой сайтом и кодировкой файла разобраться не могу
С кодировкой базы данных и сайтом файлом разобраться не могу. Я на своем сайте вывожу данные из...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru