Форум программистов, компьютерный форум CyberForum.ru

Перевести строку из одной кодировки в другую - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 22, средняя оценка - 4.68
i_SamSky
 Аватар для i_SamSky
6 / 6 / 0
Регистрация: 13.04.2012
Сообщений: 57
13.04.2012, 21:25     Перевести строку из одной кодировки в другую #1
Нужно написать программу, перекодирующую строку в кодировке KOI в строку в кодировке Windows-1251 и обратно.

Прорыскал пол-инета, но ничего интересного не нашел. Помогите, хотя бы распишите алгоритм решения :)

Предполагаемые варианты решения:
1) Считывание из файла в опр. кодировке строки, и дальнейшая "подгонка кусками" под другую кодировку, т.е. все различия между кодировками минимизировать.
2) Использовать специализированные функции, только пока непонятно какие :D
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.04.2012, 21:25     Перевести строку из одной кодировки в другую
Посмотрите здесь:

функция, которая копирует строку в другую строку заданное количество раз C++
C++ Как перевести файл из одной кодировки в другую?
C++ можно ли в с++ вызвать переменную из одной функции в другую т.е. мы переменну задали в одной функции а использовали в другой... и как это реализовать?
С одной cpp в другую C++
Класс Time. Не могу перевести на другую строку C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,621
Записей в блоге: 17
13.04.2012, 21:40     Перевести строку из одной кодировки в другую #2
Неверная кодировка текста в компонентах формы при получении почты через IdPOP3
i_SamSky
 Аватар для i_SamSky
6 / 6 / 0
Регистрация: 13.04.2012
Сообщений: 57
13.04.2012, 21:53  [ТС]     Перевести строку из одной кодировки в другую #3
C++
1
AnsiString KoiToWin(const AnsiString St)
Что же это за тип - "AnsiString"? Какой файл подключать не подскажете?
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,621
Записей в блоге: 17
13.04.2012, 22:16     Перевести строку из одной кодировки в другую #4
Что же это за тип - "AnsiString"? Какой файл подключать не подскажете?
это тип строка из С++ Builder-a
Думаю если постараться можно заменить на std::string
i_SamSky
 Аватар для i_SamSky
6 / 6 / 0
Регистрация: 13.04.2012
Сообщений: 57
13.04.2012, 22:18  [ТС]     Перевести строку из одной кодировки в другую #5
Нашел какой-то "vlc.h". На моем CodeBlocks его к сожалению нет. Нет ли какой-нибудь замены типу AnsiString?

Добавлено через 56 секунд
Цитата Сообщение от Avazart Посмотреть сообщение
...заменить на std::string
Ок, сейчас попробую.
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,621
Записей в блоге: 17
13.04.2012, 22:20     Перевести строку из одной кодировки в другую #6
Вместо St.Length() тогда St.size()
Неручаюсь за код так как не проверял...
dr.curse
 Аватар для dr.curse
386 / 342 / 16
Регистрация: 11.10.2010
Сообщений: 1,907
13.04.2012, 22:28     Перевести строку из одной кодировки в другую #7
Цитата Сообщение от Avazart Посмотреть сообщение
Вместо St.Length() тогда St.size()
можно и St.length()

Добавлено через 1 минуту
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
std::string KoiToWin(const std::string St)
{
 char Koi_WinChars[] = {
      128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
      144,145,146,147,148,149,150,151,152,153,218,155,176,157,183,159,
      160,161,162,184,186,165,166,191,168,169,170,171,172,173,174,175,
      156,177,178,168,170,181,182,175,184,185,186,187,188,189,190,185,
      254,224,225,246,228,229,244,227,245,232,233,234,235,236,237,238,
      239,255,240,241,242,243,230,226,252,251,231,248,253,249,247,250,
      222,192,193,214,196,197,212,195,213,200,201,202,203,204,205,206,
      207,223,208,209,210,211,198,194,220,219,199,216,221,217,215,218};
 std::string Result = St;
 for (int i = 1; i <= St.length(); i++)
 {
  if (int(St[i]) > 127)
    Result[i] = Koi_WinChars[St[i]];
 }
 return Result;
}
i_SamSky
 Аватар для i_SamSky
6 / 6 / 0
Регистрация: 13.04.2012
Сообщений: 57
13.04.2012, 22:41  [ТС]     Перевести строку из одной кодировки в другую #8
Пока не понимаю как, но это работает :D
Спасибо Вам :)

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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <iostream>
#include <fstream>
 
 
using namespace std;
 
string WinToKoi(const string St)
{
 char Win_KoiChars[] = {
      128,129,130,131,132,133,134,135,136,137,060,139,140,141,142,143,
      144,145,146,147,148,169,150,151,152,153,154,062,176,157,183,159,
      160,246,247,074,164,231,166,167,179,169,180,060,172,173,174,183,
      156,177,073,105,199,181,182,158,163,191,164,062,106,189,190,167,
      225,226,247,231,228,229,246,250,233,234,235,236,237,238,239,240,
      242,243,244,245,230,232,227,254,251,253,154,249,248,252,224,241,
      193,194,215,199,196,197,214,218,201,202,203,204,205,206,207,208,
      210,211,212,213,198,200,195,222,219,221,223,217,216,220,192,209};
 string Result=St;
 for (int i = 1; i <= St.length(); i++)
 {
  if (int(St[i]) > 127)
    Result[i] = Win_KoiChars[St[i]];
 }
 return Result;
}
 
//---------------------------------------------------------------------------
string KoiToWin(const string St)
{
 char Koi_WinChars[] = {
      128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
      144,145,146,147,148,149,150,151,152,153,218,155,176,157,183,159,
      160,161,162,184,186,165,166,191,168,169,170,171,172,173,174,175,
      156,177,178,168,170,181,182,175,184,185,186,187,188,189,190,185,
      254,224,225,246,228,229,244,227,245,232,233,234,235,236,237,238,
      239,255,240,241,242,243,230,226,252,251,231,248,253,249,247,250,
      222,192,193,214,196,197,212,195,213,200,201,202,203,204,205,206,
      207,223,208,209,210,211,198,194,220,219,199,216,221,217,215,218};
 string Result = St;
 for (int i = 1; i <= St.length(); i++)
 {
  if (int(St[i]) > 127)
    Result[i] = Koi_WinChars[St[i]];
 }
 return Result;
}
 
 
 
 
//--------------------------------------
int main()
{
ifstream inKOI("inputKOI.txt");
string s1;
while (!inKOI.eof())
    {
        if (inKOI.eof()) break;
        inKOI >> s1;
    }
cout << "s1: " << s1 << endl;
inKOI.close();
 
string s2;
s2=KoiToWin(s1);
cout << "s2: " << s2 << endl;
 
//---------------------------------------------
cout << endl;
ifstream inWIN("inputWin1251.txt");
string s3;
while (!inWIN.eof())
    {
        if (inWIN.eof()) break;
        inWIN >> s3;
    }
cout << "s3: " << s3 << endl;
inWIN.close();
 
string s4;
s4=WinToKoi(s3);
cout << "s4: " << s4 << endl;
 
    return 0;
}
i_SamSky
 Аватар для i_SamSky
6 / 6 / 0
Регистрация: 13.04.2012
Сообщений: 57
13.04.2012, 23:10  [ТС]     Перевести строку из одной кодировки в другую #9
Цитата Сообщение от aram_gyumri Посмотреть сообщение
C++
1
...128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143..
Что это за последовательность, не подскажете? Конечно понятно что это коды символов, но почему именно в таком порядке? Идет подгонка под другую кодировку?
dr.curse
 Аватар для dr.curse
386 / 342 / 16
Регистрация: 11.10.2010
Сообщений: 1,907
13.04.2012, 23:13     Перевести строку из одной кодировки в другую #10
Цитата Сообщение от i_SamSky Посмотреть сообщение
Что это за последовательность, не подскажете? Конечно понятно что это коды символов, но почему именно в таком порядке? Идет подгонка под другую кодировку?
i_SamSky, я сам незнаю просто перевел код чтоб без AnsiString работало
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,621
Записей в блоге: 17
13.04.2012, 23:15     Перевести строку из одной кодировки в другую #11
Походу таблица соответствий символов
i_SamSky
 Аватар для i_SamSky
6 / 6 / 0
Регистрация: 13.04.2012
Сообщений: 57
14.04.2012, 15:51  [ТС]     Перевести строку из одной кодировки в другую #12
C++
1
2
3
4
5
6
. . . . . .
if (int(St[i]) > 127)
{
   Result[i] = Win_KoiChars[St[i]];
}
. . . . . .
После детального рассмотрения, понял что функция не работает. Точнее не выполняется условие в функции ни при каких обстоятельствах (весь алфавит забивал в строку и прогонял через функцию).

Позже попытался заменить хотя бы один символ...
C++
1
2
3
4
5
6
7
8
9
10
11
12
string WinToKoi2(const string St)
{
    string Result=St;
    for (int i = 0; i <= St.length(); i++)
    {
    if (int(St[i]) == 130)
    {
        Result[i] = St[i]+55; //55 - неточное значение, не обращайте внимания, это приблизительно
    }
 }
    return Result;
}
С помощью этой функции пытаюсь найти символ с кодом 130, т.е. В (русская), и заменить на аналогичный символ из KOI. Задаю строку с набором букв "АБВГДЕЖ..." и прогоняю ее через функцию, но 130 символ, т.е. В, почему-то не находится, в следствие чего условие не выполняется.

Так в чем же проблема, подскажите :)
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,621
Записей в блоге: 17
14.04.2012, 17:27     Перевести строку из одной кодировки в другую #13
Я тоже догадываля что эти ф-ции не работают, почитал
http://www.script-coding.com/CodePages.html
Многое прояснило.
Как я понял при декодировании надо изменять символы которые
0x00С0 >= ch && ch <= 0x00FF согласно таблицам ( эти символы соответствуют кириллице)

Добавлено через 5 минут
Вот написал ф-цию из KOI8-R в Unicode
IdPOP3. Проверка почты на mail.ru. Неверная кодировка текста.
i_SamSky
 Аватар для i_SamSky
6 / 6 / 0
Регистрация: 13.04.2012
Сообщений: 57
14.04.2012, 23:07  [ТС]     Перевести строку из одной кодировки в другую #14
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
string WinToKoi2(const string St)
{
    string Result=St;
     for (int i = 0; i <= St.length(); i++)
 {
    if (  (int(St[i]) == -64) || (int(St[i]) == -63) || (int(St[i]) == -56) || (int(St[i]) == -55)
       || (int(St[i]) == -54) || (int(St[i]) == -53) || (int(St[i]) == -52) || (int(St[i]) == -51)
       || (int(St[i]) == -50) || (int(St[i]) == -49)
       )
        Result[i] = St[i]+33;
 
    if ( int(St[i]) == -62) Result[i]=St[i]+53;
    if ( int(St[i]) == -61) Result[i]=St[i]+36;
    if ( int(St[i]) == -60 || int(St[i]) == -59)
        Result[i]=St[i]+32;
    if ( int(St[i]) == -58) Result[i]=St[i]+48;
    if ( int(St[i]) == -57) Result[i]=St[i]+51;
    if ( int(St[i]) == -48 || int(St[i]) == -47 || int(St[i]) == -46 || int(St[i]) == -45)
        Result[i]=St[i]+34;
    if ( int(St[i]) == -44) Result[i]=St[i]+18;
    if ( int(St[i]) == -43) Result[i]=St[i]+19;
    if ( int(St[i]) == -42) Result[i]=St[i]+13;
    if ( int(St[i]) == -41) Result[i]=St[i]+39;
    if ( int(St[i]) == -40) Result[i]=St[i]+35;
    if ( int(St[i]) == -39) Result[i]=St[i]+36;
    if ( int(St[i]) == -38) Result[i]=St[i]+37;
    if ( int(St[i]) == -37 || int(St[i]) == -36)
        Result[i]=St[i]+29;
    if ( int(St[i]) == -35) Result[i]=St[i]+31;
    if ( int(St[i]) == -34) Result[i]=St[i]+2;
    if ( int(St[i]) == -33) Result[i]=St[i]+18;
 }
    return Result;
}
Знаю, что это садомазохизм, но все же я кое-как написал функцию :D
Буду рад тому, кто найдет во всем этом определенную последовательность и сделает ее покороче.

P.S.: При написании программы выяснилось, что коды символов уезжают в минус почему-то.
P.S.S: Функция пока что переводит только заглавные русские буквы из одной кодировки в другую, до маленьких руки еще не дошли.
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,621
Записей в блоге: 17
14.04.2012, 23:53     Перевести строку из одной кодировки в другую #15
Здесь что -то не то не должно быть отрицательных чисел.
i_SamSky
 Аватар для i_SamSky
6 / 6 / 0
Регистрация: 13.04.2012
Сообщений: 57
14.04.2012, 23:57  [ТС]     Перевести строку из одной кодировки в другую #16
Цитата Сообщение от Avazart Посмотреть сообщение
Здесь что -то не то не должно быть отрицательных чисел.
Однако только так это у меня работает. Условие на стандартные положительные десятичные коды никак не реагирует.
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,621
Записей в блоге: 17
15.04.2012, 00:16     Перевести строку из одной кодировки в другую #17
Что-то у меня подозрения на то что это не win, а какой нибудь обрезаный юникод или че нить такое, попробуйте заменить
string на wstring.
Не пробовали анализировать коды символов KOI то есть кракозяблы выдавать как int?
И желательно int в hex форме что-бы можно было сравнить с таблицой
i_SamSky
 Аватар для i_SamSky
6 / 6 / 0
Регистрация: 13.04.2012
Сообщений: 57
15.04.2012, 00:25  [ТС]     Перевести строку из одной кодировки в другую #18
Цитата Сообщение от Avazart Посмотреть сообщение
...кракозяблы выдавать как int
Если я Вас правильно понял, то пытался. В файл записывалось все как и положено, со 192 позиции шел региональный алфавит, т.е. русский.
Вот так:
C++
1
2
3
4
5
6
7
ofstream KoiCode("KoiCode.txt");
for (int i=128; i<=255; i++)
{
    int trer=i; char test=trer;
    KoiCode << test << trer << " ";
}
KoiCode.close();
А насчет win1251 и ansi, у меня различий нет.
Миниатюры
Перевести строку из одной кодировки в другую  
Avazart
 Аватар для Avazart
6904 / 5144 / 253
Регистрация: 10.12.2010
Сообщений: 22,621
Записей в блоге: 17
15.04.2012, 00:34     Перевести строку из одной кодировки в другую #19
Я имел ввиду коды Юникода, возможно если их обрезать преобразовав к Аnsi то получатся отрицательные числа, поэтому и советую перейти к wstring
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.04.2012, 11:19     Перевести строку из одной кодировки в другую
Еще ссылки по теме:

Перевести L студентов с 1-й группы в другую (списки) C++
Перевести длинную бинарную строку в строку с десятичными цифрами C++
C++ Перекодировать строку из кодировки KOI в кодировку Windows-1251 и обратно

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

Или воспользуйтесь поиском по форуму:
i_SamSky
 Аватар для i_SamSky
6 / 6 / 0
Регистрация: 13.04.2012
Сообщений: 57
15.04.2012, 11:19  [ТС]     Перевести строку из одной кодировки в другую #20
Вот написал для теста...
C++
1
2
3
4
5
6
7
8
9
10
ofstream Test("Test.txt");
string str1="АБВГД";
wstring str2(str1.begin(), str1.end()); 
     for (int i = 0; i <= str2.length(); i++)
 {
    Test << int(str2[i]) << " ";
 }
string str3(str2.begin(), str2.end());
Test << endl << str3;
Test.close();
Результат работы:
C++
1
2
65472 65473 65474 65475 65476 0 
юабцд
Только теперь я запутался... Мне теперь надо считывать строку из файла KOI/Win1251, преобразовывать к "Unicode" и дальше работать с юникодом, все преобразования вести с ним?
Yandex
Объявления
15.04.2012, 11:19     Перевести строку из одной кодировки в другую
Ответ Создать тему
Опции темы

Текущее время: 01:37. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru