String to windows 1251

Tester64

420 / 357 / 47

Регистрация: 22.05.2013

Сообщений: 2,518

31.08.2014, 19:10. Показов 21955. Ответов 22

Метки нет (Все метки)


Нашел пример:

C++ (Qt)
1
2
3
4
5
6
7
8
9
10
11
12
    wchar_t s[] = L"London Москва";
    char utf8[100];
    wchar_t wstr[100];
    char s1251[100];
    WideCharToMultiByte(CP_UTF8, 0, s, -1, utf8, 100, NULL, NULL);
    utf8[WideCharToMultiByte(CP_UTF8, 0, s, -1, utf8, 0, NULL, NULL)]='\0';
    // Подготовили строку UTF8 дальше идет ее преобразование в 1251
    MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, 100);
    wstr[MultiByteToWideChar(CP_UTF8, 0, utf8, -1, wstr, 0)];
    WideCharToMultiByte(1251, 0, wstr, -1, s1251, 100, NULL, NULL);
    utf8[WideCharToMultiByte(1251, 0, wstr, -1, s1251, 0, NULL, NULL)]='\0';
    printf("%s\n", s1251);

Шикарно работает в консоли, но ОЧЕНЬ надо пределать его в функции со String

C++ (Qt)
1
2
3
4
5
std::string UTF8_to_1251(const std::string ss) {
   //...
}
...
printf(UTF8_to_1251("London Москва"));

Но знаний по преобразованию строк в char и назад не хватает! Только начал вычитывать, а функция нужна срочно!
Помогите хоть немножко!



0



Ryzhikov_A

6 / 6 / 0

Регистрация: 14.10.2012

Сообщений: 36

31.08.2014, 20:09

Для перехода от string к const char* (неизменяемому массиву символов в куче) используйте метод c_str():

C++
1
const char* cLikeString = <объект типа string>.c_str();

Для создания строки типа string из массива символов просто вызовите конструктор.

C++
1
2
char* cLikeString = ...;
std::string cppLikeString(cLikeString );

Добавлено через 6 минут
p.s. Вы используете массивы символов на стеке (char arrayName[]). Вместо используемого выше варианта с указателями(char*) вполне можно использовать и их, синтаксис останется таким же. (вызов std::string(arrayName) эквивалентен std::string(&arrayName[0]), т.е. arrayName в данном случае приводится к char*)



1



420 / 357 / 47

Регистрация: 22.05.2013

Сообщений: 2,518

31.08.2014, 21:04

 [ТС]

Вторая часть кода подошла, но не первая. Она работает, но мне нужно другое:
std::string (или std::wstring) в wchar_t



0



Ryzhikov_A

6 / 6 / 0

Регистрация: 14.10.2012

Сообщений: 36

31.08.2014, 21:22

Аналогично

C++
1
2
std::wstring line(L"test string");
const wchar_t* szName = line.c_str();



1



DrOffset

19456 / 10069 / 2451

Регистрация: 30.01.2014

Сообщений: 17,749

31.08.2014, 21:49

Сообщение было отмечено Tester64 как решение

Решение

Tester64, тут еще ведь нужно понимать, что L»строка» — это не UTF8. Это скорее UTF16 или USC2, если рассматривать windows.
Конвертирование же именно UTF8 в CP1251 под windows можно так сделать:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
std::string UTF8_to_CP1251(std::string const & utf8)
{
    if(!utf8.empty())
    {
        int wchlen = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), utf8.size(), NULL, 0);
        if(wchlen > 0 && wchlen != 0xFFFD)
        {
            std::vector<wchar_t> wbuf(wchlen);
            MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), utf8.size(), &wbuf[0], wchlen);
            std::vector<char> buf(wchlen);
            WideCharToMultiByte(1251, 0, &wbuf[0], wchlen, &buf[0], wchlen, 0, 0);
 
            return std::string(&buf[0], wchlen);
        }
    }
    return std::string();
}



1



Tester64

420 / 357 / 47

Регистрация: 22.05.2013

Сообщений: 2,518

31.08.2014, 22:25

 [ТС]

ИДЕАЛЬНО!
Правда прилось еще добавить

C++ (Qt)
1
#include <vector>

(я как новичок этого не знал)



0



383 / 281 / 31

Регистрация: 04.09.2009

Сообщений: 1,225

01.09.2014, 01:47

Хм, все бегут без оглядки от CP1251 и от всяких понаехавших «кодовых страниц», а тут наоборот, UTF-8 не нравится



0



19456 / 10069 / 2451

Регистрация: 30.01.2014

Сообщений: 17,749

01.09.2014, 01:50

Сообщение от gromo

Хм, все бегут без оглядки от CP1251, а тут наоборот, UTF-8 не нравится

Пусть сам налетает на все грабли
Всех все равно не переубедишь. Я тут сперва написал большой пост про пользу юникода и почему подстраиваться под устаревшую вин консоль (с дос кодировкой по умолчанию) не обязательно, но потом стер.



0



420 / 357 / 47

Регистрация: 22.05.2013

Сообщений: 2,518

01.09.2014, 03:48

 [ТС]

Сообщение от gromo

Хм, все бегут без оглядки от CP1251 и от всяких понаехавших «кодовых страниц», а тут наоборот, UTF-8 не нравится

Сообщение от DrOffset

про пользу юникода и почему подстраиваться под устаревшую вин консоль (с дос кодировкой по умолчанию) не обязательно

Считайте капризом! Работаю под виндой. Пишу в блокноте (notepad++) без IDE. Компилирую батником. Код не большой. Самое главное — скорость сборки. А не удобство редактора и выпадающие подсказки. Результат вывожу в универсальную виндовую консоль. Как перепрошить всю винду с анси на юникод не знаю, да и не хочу — другие программы «крокозябры» писать будут (включая RAR и 7ZIP). Написал функцию — Rep(«привет мир») — выводящую строку с результатом в консоль. В нее-же зашил анси. Все исходники (текстовики СРР и Н) храню в юникоде (где-то вычитал что это любимая кодировка g++ и NDK). Rep вызываю редко, но не хочу заморачиваться с перекодированием системной консоли на чужих машинах (или писать транслитом или вспоминать как это зовется на английском). Под линукс (если перейду) сделаю другой Rep. Под андроид третий (уже сделал). Команда одна, но сама решает что и как выводить. И главное без заморочек с кодировкой на входе. Смогу одной константой отключить перекодирование, но пока… Так удобнее! Да и учусь я пока. Простые утилитки пишу, базовые конструкции тестирую…

Пока-что перевод нужен был ТОЛЬКО для отладочных сообщений в консоль, хотя бывает необходимость и при работе с файлами кодировку заменить и со старым сервером через сеть пообщаться… Пусть себе лежит в коллекции. Заодно понял как строки конвертировать между разными типами (char-wchar-string), а это похоже крайне необохдимые знания в с++

p.s. Для ускорения вызова батников даже утилиту на делфи написал для вызова батников по горячим клавишам. И их принудильного перезапуска (перекомпиляция). ИМХО самое быстрое изученение… IDE много перепробовал — все тормозят сильно. Сборка пустышки под VC++ занимала минимум 20-30 секунд. Как и под DevCPP. Консоль (когда тормозит) за 7-8 секунд собирает, а если ускоряется около 3х секунд (почти догнал паскаль)…



0



Ушел с форума

16478 / 7441 / 1187

Регистрация: 02.05.2013

Сообщений: 11,617

Записей в блоге: 1

01.09.2014, 09:43

Сообщение от Tester64

Как перепрошить всю винду с анси на юникод не знаю, да и не хочу — другие программы «крокозябры» писать будут (включая RAR и 7ZIP).

Не нужно ничего «перепрошивать», Windows уже лет 15 юникодная изнутри.



0



Модератор

5287 / 2375 / 342

Регистрация: 20.02.2013

Сообщений: 5,773

Записей в блоге: 20

01.09.2014, 09:54

Сообщение от DrOffset

Я тут сперва написал большой пост про пользу юникода и почему подстраиваться под устаревшую вин консоль (с дос кодировкой по умолчанию) не обязательно, но потом стер.

Ну и зачем стёр? Многим наверное было бы и полезно и интересно. Мне вот, например, интересно.



0



2687 / 2259 / 244

Регистрация: 03.07.2012

Сообщений: 8,228

Записей в блоге: 1

01.09.2014, 10:28

Можно в вики почитать про юникод. Вообще, по нему полно ресурсов, например кратко и популярно: http://zelserg.livejournal.com/2570.html



1



Tester64

420 / 357 / 47

Регистрация: 22.05.2013

Сообщений: 2,518

01.09.2014, 18:06

 [ТС]

Сообщение от Убежденный

Windows уже лет 15 юникодная изнутри

Не знаю с какой стороны она изнутри юникоидная… Но консоль осталась в 1251. Вроде читал где-то что это можно поменять — то-ли подменой шрифтов, то-ли шаманством в реестре. Но все программы которые хотят вывести в консоль кирилицу используют 1251. Включая bat-файлы. Попробуйте в Win bat-файл в юникоде кирилицу вставить:

Bash
1
echo Привет

Не уверен что после хака консоли даже стандартные команды вроде dir кирилистические названия файлов правильно выводить будут (сейчас выводят)

А что такое юникод и чем он отличается от других кодировок, я думаю большинство и так знает. Но у него есть и свои минусы! По делфям помню (переводил проект с Delphi7 на Delphi2009) — каждый символ кодируется не одним байтом (как в других кодировках), от 2х до 4х!. Причем это плавающая величина и зависит от языка. И хранение в файлах и в памяти подобных строк увеличилось в 2-4 раза. Причем есть разные реализации юникода в разных ОС. Старые не поддерживали 4 а значит возможен глюк.

Добавлено через 11 минут
А вообще, инетересно, кто-нибудь (из Вас) еще кодит для консоли? Под Win или Linux? Слышал (активно не работал) что весь линукс работает в консоли и в основном написана на с/с++



0



DrOffset

19456 / 10069 / 2451

Регистрация: 30.01.2014

Сообщений: 17,749

01.09.2014, 18:26

Сообщение от Tester64

Не знаю с какой стороны она изнутри юникоидная…

Windows юникодная изнутри. Консоль не юникодная по-умолчанию, и это сделано по всей видимости лишь для совместимости со старым ПО. Если мы пишем новое ПО нет никакой нужды подстраиваться под это. В VS например достаточно написать:

C++
1
_setmode(_fileno(stdout), _O_U16TEXT);

Чтобы перевести консоль в режим UTF16, соответственно, при наличии правильных шрифтов, wcout, wstring будут работать без каких-либо перекодировок.

Сообщение от Tester64

Но консоль осталась в 1251

По-умолчанию она вообще в 866 кодировке (ДОС) в русской windows.

Сообщение от Tester64

Слышал (активно не работал) что весь линукс работает в консоли и в основном написана на с/с++

Ну это не правда, что прям весь . Но консольные утилиты там гораздо лучше себя чувствуют, чем в windows, в том числе засчет развитой командной оболочки. Кстати в любом линуксе по-умолчанию используется кодировка юникода UTF-8.



0



4820 / 2286 / 287

Регистрация: 01.03.2013

Сообщений: 5,970

Записей в блоге: 30

01.09.2014, 23:23

Сообщение от gru74ik

Ну и зачем стёр? Многим наверное было бы и полезно и интересно. Мне вот, например, интересно.

+1. Мне тоже всегда интересно почитать имхи специалистов, тем более, если им можно потом еще задать вопрос. А вики мы в любом случае почитать можем.



1



Модератор

5287 / 2375 / 342

Регистрация: 20.02.2013

Сообщений: 5,773

Записей в блоге: 20

02.09.2014, 06:46

Сообщение от Tester64

Слышал (активно не работал) что весь линукс работает в консоли

Там всё вполне себе цивилизованно — окошечки, менюшечки. Попробуй ради интереса Ubuntu поставить, к примеру. Посмотришь сам.



0



420 / 357 / 47

Регистрация: 22.05.2013

Сообщений: 2,518

02.09.2014, 17:36

 [ТС]

Сообщение от gru74ik

Там всё вполне себе цивилизованно — окошечки, менюшечки. Попробуй ради интереса Ubuntu поставить, к примеру. Посмотришь сам

«По приколу» делать это не хочется, а для работы не нужно (на 80% привязан к винде — остальное веб). Конечно раньше ставил (в виртуальные машины), даже где-то в коллекции лежит… Конечно там можно включить графику и работать только в ней. Но меня инетересует не это! Насколько сейчас активно кодят под консоль в С++? Нужна ли эта технология еще? Или давно замещена графикой? Конечно понимаю, что все сетевые технологии консольные, но кроме сетей?



0



19456 / 10069 / 2451

Регистрация: 30.01.2014

Сообщений: 17,749

02.09.2014, 18:17

Сообщение от Tester64

Насколько сейчас активно кодят под консоль в С++?

Нет такого понятия «кодить под консоль».
Есть прикладное ПО, которое может быть с графическим или текстовым интерфейсом. Пользовательский интерфейс — это только малая часть процесса разработки ПО, поэтому вакансии «кодить под консоль» и не найдешь. Потому что обычно «кодят», чтобы решить некую задачу, а текстовый у этой программы будет интерфейс или графический — это не столь важно, это системные архитекторы и дизайнеры пусть решают.
Причем, помимо прикладного ПО есть еще куча разного системного и околосистемного софта: сервисы, библиотеки, драйвера, embedded ПО, ядра ОС, физические движки игр и т.д. и т.п., для которых вообще не применимо понятие пользовательский интерфейс (или этот интерфейс штука специфическая, например две кнопки на устройстве вкл. и выкл.). Эта категория тоже занимает довольно ощутимую долю рынка. Мы ее не рассматриваем что ли?



1



Модератор

8532 / 3313 / 105

Регистрация: 24.05.2011

Сообщений: 14,492

Записей в блоге: 8

02.09.2014, 20:58

Сообщение от Tester64

весь линукс работает в консоли

Я вас умоляю! Для повышения вашего уровня эрудиции в этом вопросе крайне рекомендую зайти хотя бы в Windows vs Linux (0Dh) или У кого как выглядит рабочий стол? (2), где вполне достаточно скринов рабстолов линукс



0



Optimus11

-41 / 49 / 5

Регистрация: 10.01.2017

Сообщений: 1,915

05.11.2020, 14:09

Сообщение от DrOffset

Tester64, тут еще ведь нужно понимать, что L»строка» — это не UTF8. Это скорее UTF16 или USC2, если рассматривать windows.
Конвертирование же именно UTF8 в CP1251 под windows можно так сделать:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
std::string UTF8_to_CP1251(std::string const & utf8)
{
    if(!utf8.empty())
    {
        int wchlen = MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), utf8.size(), NULL, 0);
        if(wchlen > 0 && wchlen != 0xFFFD)
        {
            std::vector<wchar_t> wbuf(wchlen);
            MultiByteToWideChar(CP_UTF8, 0, utf8.c_str(), utf8.size(), &wbuf[0], wchlen);
            std::vector<char> buf(wchlen);
            WideCharToMultiByte(1251, 0, &wbuf[0], wchlen, &buf[0], wchlen, 0, 0);
 
            return std::string(&buf[0], wchlen);
        }
    }
    return std::string();
}

Я немного запутался, разве MultiByteToWideChar — может конвертировать из UTF8 в CP1251 ?
Вроде бы MultiByteToWideChar — конвертирует Из указанной в первом параметре кодировке —> всегда в UTF-16 ?

Добавлено через 5 минут
Блин, понял, сначала конвертируем из UTF8 в UTF16, а потом из UTF16 в CP1251.

А с точки зрения производительности — это ж двойные затраты получаются ? Может есть более быстрый способ конвертации между кодировками ?



0



raxper

Эксперт

30234 / 6612 / 1498

Регистрация: 28.12.2010

Сообщений: 21,154

Блог

05.11.2020, 14:09

20

Конвертирует строку из UTF-8 в Windows-1251

static string UTF8ToWin1251(string sourceStr)
{
Encoding utf8 = Encoding.UTF8;
Encoding win1251 = Encoding.GetEncoding(«Windows-1251»);
byte[] utf8Bytes = utf8.GetBytes(sourceStr);
byte[] win1251Bytes = Encoding.Convert(utf8, win1251, utf8Bytes);
return win1251.GetString(win1251Bytes);
}

Конвертирует строку из Windows-1251 в UTF-8

static private string Win1251ToUTF8(string source)
{
Encoding utf8 = Encoding.GetEncoding(«utf-8»);
Encoding win1251 = Encoding.GetEncoding(«windows-1251»);
byte[] utf8Bytes = win1251.GetBytes(source);
byte[] win1251Bytes = Encoding.Convert(win1251, utf8, utf8Bytes);
source = win1251.GetString(win1251Bytes);
return source;
}

Welcome to our comprehensive guide on Windows-1251 encoding in Java! If you’re a developer looking to understand character encoding and how to effectively handle Cyrillic text in your Java applications, you’re in the right place. This page will provide you with essential insights into the Windows-1251 encoding standard, its importance for processing text in languages like Russian, and practical examples of how to implement it in your Java code. Whether you’re troubleshooting encoding issues or seeking to enhance your software’s internationalization capabilities, you’ll find valuable tips and techniques to elevate your programming skills. Let’s dive into the world of Windows-1251 encoding and unlock the potential of Java for multilingual applications!

Introduction to Windows-1251

Windows-1251 is a character encoding standard developed by Microsoft for the representation of Cyrillic scripts. It was designed to accommodate languages that use the Cyrillic alphabet, including Russian, Ukrainian, and Bulgarian. As a single-byte character encoding, Windows-1251 can represent 256 different characters, making it a popular choice for applications dealing with Eastern European languages. Despite the growing adoption of Unicode, Windows-1251 remains relevant in legacy systems and specific applications that require Cyrillic text processing.

In Java, encoding text with Windows-1251 is straightforward. The Java platform provides built-in support for various character encodings, including Windows-1251. To encode a string into a byte array using Windows-1251, you can use the getBytes method of the String class, specifying the encoding as an argument. Here’s an example:

import java.nio.charset.Charset;
public class EncodeExample {
    public static void main(String[] args) {
        String text = "Привет, мир!"; // "Hello, World!" in Russian
        byte[] encodedBytes = text.getBytes(Charset.forName("Windows-1251"));
        
        // Print the encoded byte array
        System.out.println("Encoded bytes: " + java.util.Arrays.toString(encodedBytes));
    }
}

This code snippet demonstrates how to convert a string containing Cyrillic characters into its Windows-1251 encoded byte representation. It’s essential to use the correct character set to avoid data corruption.

Decoding with Windows-1251 in Java

Decoding text encoded in Windows-1251 back into a Java String is equally simple. The String constructor can be utilized, which takes a byte array and the desired charset as parameters. Here’s how you can decode Windows-1251 encoded data:

import java.nio.charset.Charset;
public class DecodeExample {
    public static void main(String[] args) {
        byte[] encodedBytes = { -24, -112, -108, -24, -111, -100, -24, -113, -101, -24, -112, -116 }; // Example byte array
        String decodedText = new String(encodedBytes, Charset.forName("Windows-1251"));
        
        // Print the decoded string
        System.out.println("Decoded text: " + decodedText);
    }
}

In this example, we convert a byte array back into a string using Windows-1251 encoding. It’s crucial to ensure the byte array accurately represents the original text; otherwise, the output may contain garbled characters.

Advantages and Disadvantages of Windows-1251

Advantages

  1. Simplicity: Windows-1251 is easy to implement, especially in legacy systems where the character set is well-defined.
  2. Efficiency: Being a single-byte encoding, it can be more memory-efficient for applications that primarily deal with Cyrillic text compared to multi-byte encodings like UTF-8.

Disadvantages

  1. Limited Character Set: Windows-1251 only supports Cyrillic characters, which can be limiting for applications that require multilingual support.
  2. Obsolescence: As the Unicode standard gains traction, Windows-1251 is gradually becoming less common, leading to potential compatibility issues in modern applications.

Key Applications of Windows-1251

Windows-1251 is commonly used in various applications, particularly those involving legacy systems or specific Eastern European contexts. Key applications include:

  • Text Processing: Software that processes Cyrillic text, such as word processors and text editors, often utilizes Windows-1251 encoding.
  • Databases: Some databases may still store data in Windows-1251, especially if they were developed before the widespread adoption of Unicode.
  • Web Development: Older websites that cater to Russian or other Cyrillic language audiences may still use Windows-1251 encoding for their content.

Popular Frameworks and Tools for Windows-1251

Several frameworks and tools support Windows-1251 encoding, making it easier for developers to work with Cyrillic text. Some of the most popular include:

  • Apache Commons Text: This library provides utilities for encoding and decoding various character sets, including Windows-1251.
  • Java’s Built-in Libraries: The standard Java libraries offer robust support for Windows-1251 through the Charset class, enabling seamless encoding and decoding.
  • Spring Framework: This popular Java framework supports various character encodings, allowing developers to easily integrate Windows-1251 in web applications.

In conclusion, while Windows-1251 may not be the most modern encoding standard, it still holds significance in specific use cases, especially when dealing with Cyrillic text in Java applications. Understanding how to encode and decode using this standard is essential for developers working in Eastern European contexts.

Для конвертации на php строки из utf-8 в windows-1251 и наоборот, можно использовать следующую функцию:

Описание функции iconv:
string iconv ( string from_kodirovka, string to_kodirovka, string str )
Производит преобразование кодировки символов строки str из начальной кодировки from_kodirovka в конечную to_kodirovka. Возвращает строку в новой кодировке, или FALSE в случае ошибки.

Если добавить //TRANSLIT к параметру out_charset будет включена транслитеризация. Это означает, что вслучае, когда символа нет в конечной кодировке, он заменяется одним или несколькими аналогами. Если добавить //IGNORE, то символы, которых нет в конечной кодировке, будут опущены. Иначе, будет возвращена строка str, обрезанная до первого недопустимого символа.

В случае, если ваш хостинг не поддерживает iconv, для конвертации из utf-8 в win-1251 и наоборот можно использовать следующие функции:

function utf8_to_cp1251($s) {
    $tbl = $GLOBALS['unicode_to_cp1251_tbl'];
    $uc = 0;
    $bits = 0;
    $r = "";
    for($i = 0, $l = strlen($s); $i < $l; $i++) {
        $c = $s{$i};
        $b = ord($c);
        if($b & 0x80) {
            if($b & 0x40) {
                if($b & 0x20) {
                    $uc = ($b & 0x0F) << 12;
                    $bits = 12;
                } else {
                    $uc = ($b & 0x1F) << 6;
                    $bits = 6;
                }
            } else {
                $bits -= 6;
                if($bits) {
                    $uc |= ($b & 0x3F) << $bits;
                } else {
                    $uc |= $b & 0x3F;
                    if($cc = @$tbl[$uc]) {
                        $r .= $cc;
                    } else {
                        $r .= '?';
                    }
                }
            }
        } else {
            $r .= $c;
        }
    }
    return $r;
}
function cp1251_to_utf8($s) {
    $tbl = $GLOBALS['cp1251_to_utf8_tbl'];
    $r = "";
    for($i = 0, $l = strlen($s); $i < $l; $i++) {
        $c = $s{$i};
        $b = ord($c);
        if ($b < 128) {
            $r .= $c;
        } else {
            $r .= @$tbl[$b];
        }
    }
    return $r; 
} 

$unicode_to_cp1251_tbl = array(
0x0402 => "\x80", 
0x0403 => "\x81", 
0x201A => "\x82", 
0x0453 => "\x83", 
0x201E => "\x84", 
0x2026 => "\x85", 
0x2020 => "\x86", 
0x2021 => "\x87", 
0x20AC => "\x88", 
0x2030 => "\x89", 
0x0409 => "\x8A", 
0x2039 => "\x8B", 
0x040A => "\x8C", 
0x040C => "\x8D", 
0x040B => "\x8E", 
0x040F => "\x8F", 
0x0452 => "\x90", 
0x2018 => "\x91", 
0x2019 => "\x92", 
0x201C => "\x93", 
0x201D => "\x94", 
0x2022 => "\x95", 
0x2013 => "\x96", 
0x2014 => "\x97", 
0x2122 => "\x99", 
0x0459 => "\x9A", 
0x203A => "\x9B", 
0x045A => "\x9C", 
0x045C => "\x9D", 
0x045B => "\x9E", 
0x045F => "\x9F", 
0x00A0 => "\xA0", 
0x040E => "\xA1", 
0x045E => "\xA2", 
0x0408 => "\xA3", 
0x00A4 => "\xA4", 
0x0490 => "\xA5", 
0x00A6 => "\xA6", 
0x00A7 => "\xA7", 
0x0401 => "\xA8", 
0x00A9 => "\xA9", 
0x0404 => "\xAA", 
0x00AB => "\xAB", 
0x00AC => "\xAC", 
0x00AD => "\xAD", 
0x00AE => "\xAE", 
0x0407 => "\xAF", 
0x00B0 => "\xB0", 
0x00B1 => "\xB1", 
0x0406 => "\xB2", 
0x0456 => "\xB3", 
0x0491 => "\xB4", 
0x00B5 => "\xB5", 
0x00B6 => "\xB6", 
0x00B7 => "\xB7", 
0x0451 => "\xB8", 
0x2116 => "\xB9", 
0x0454 => "\xBA", 
0x00BB => "\xBB", 
0x0458 => "\xBC", 
0x0405 => "\xBD", 
0x0455 => "\xBE", 
0x0457 => "\xBF", 
0x0410 => "\xC0", 
0x0411 => "\xC1", 
0x0412 => "\xC2", 
0x0413 => "\xC3", 
0x0414 => "\xC4", 
0x0415 => "\xC5", 
0x0416 => "\xC6", 
0x0417 => "\xC7", 
0x0418 => "\xC8", 
0x0419 => "\xC9", 
0x041A => "\xCA", 
0x041B => "\xCB", 
0x041C => "\xCC", 
0x041D => "\xCD", 
0x041E => "\xCE", 
0x041F => "\xCF", 
0x0420 => "\xD0", 
0x0421 => "\xD1", 
0x0422 => "\xD2", 
0x0423 => "\xD3", 
0x0424 => "\xD4", 
0x0425 => "\xD5", 
0x0426 => "\xD6", 
0x0427 => "\xD7", 
0x0428 => "\xD8", 
0x0429 => "\xD9", 
0x042A => "\xDA", 
0x042B => "\xDB", 
0x042C => "\xDC", 
0x042D => "\xDD", 
0x042E => "\xDE", 
0x042F => "\xDF", 
0x0430 => "\xE0", 
0x0431 => "\xE1", 
0x0432 => "\xE2", 
0x0433 => "\xE3", 
0x0434 => "\xE4", 
0x0435 => "\xE5", 
0x0436 => "\xE6", 
0x0437 => "\xE7", 
0x0438 => "\xE8", 
0x0439 => "\xE9", 
0x043A => "\xEA", 
0x043B => "\xEB", 
0x043C => "\xEC", 
0x043D => "\xED", 
0x043E => "\xEE", 
0x043F => "\xEF", 
0x0440 => "\xF0", 
0x0441 => "\xF1", 
0x0442 => "\xF2", 
0x0443 => "\xF3", 
0x0444 => "\xF4", 
0x0445 => "\xF5", 
0x0446 => "\xF6", 
0x0447 => "\xF7", 
0x0448 => "\xF8", 
0x0449 => "\xF9", 
0x044A => "\xFA", 
0x044B => "\xFB", 
0x044C => "\xFC", 
0x044D => "\xFD", 
0x044E => "\xFE", 
0x044F => "\xFF",
); 

$cp1251_to_utf8_tbl = array( 
0x80 => "\xD0\x82", 
0x81 => "\xD0\x83", 
0x82 => "\xE2\x80\x9A", 
0x83 => "\xD1\x93", 
0x84 => "\xE2\x80\x9E", 
0x85 => "\xE2\x80\xA6", 
0x86 => "\xE2\x80\xA0", 
0x87 => "\xE2\x80\xA1", 
0x88 => "\xE2\x82\xAC", 
0x89 => "\xE2\x80\xB0", 
0x8A => "\xD0\x89", 
0x8B => "\xE2\x80\xB9", 
0x8C => "\xD0\x8A", 
0x8D => "\xD0\x8C", 
0x8E => "\xD0\x8B", 
0x8F => "\xD0\x8F", 
0x90 => "\xD1\x92", 
0x91 => "\xE2\x80\x98", 
0x92 => "\xE2\x80\x99", 
0x93 => "\xE2\x80\x9C", 
0x94 => "\xE2\x80\x9D", 
0x95 => "\xE2\x80\xA2", 
0x96 => "\xE2\x80\x93", 
0x97 => "\xE2\x80\x94", 
0x99 => "\xE2\x84\xA2", 
0x9A => "\xD1\x99", 
0x9B => "\xE2\x80\xBA", 
0x9C => "\xD1\x9A", 
0x9D => "\xD1\x9C", 
0x9E => "\xD1\x9B", 
0x9F => "\xD1\x9F", 
0xA0 => "\xC2\xA0", 
0xA1 => "\xD0\x8E", 
0xA2 => "\xD1\x9E", 
0xA3 => "\xD0\x88", 
0xA4 => "\xC2\xA4", 
0xA5 => "\xD2\x90", 
0xA6 => "\xC2\xA6", 
0xA7 => "\xC2\xA7", 
0xA8 => "\xD0\x81", 
0xA9 => "\xC2\xA9", 
0xAA => "\xD0\x84", 
0xAB => "\xC2\xAB", 
0xAC => "\xC2\xAC", 
0xAD => "\xC2\xAD", 
0xAE => "\xC2\xAE", 
0xAF => "\xD0\x87", 
0xB0 => "\xC2\xB0", 
0xB1 => "\xC2\xB1", 
0xB2 => "\xD0\x86", 
0xB3 => "\xD1\x96", 
0xB4 => "\xD2\x91", 
0xB5 => "\xC2\xB5", 
0xB6 => "\xC2\xB6", 
0xB7 => "\xC2\xB7", 
0xB8 => "\xD1\x91", 
0xB9 => "\xE2\x84\x96", 
0xBA => "\xD1\x94", 
0xBB => "\xC2\xBB", 
0xBC => "\xD1\x98", 
0xBD => "\xD0\x85", 
0xBE => "\xD1\x95", 
0xBF => "\xD1\x97", 
0xC0 => "\xD0\x90", 
0xC1 => "\xD0\x91", 
0xC2 => "\xD0\x92", 
0xC3 => "\xD0\x93", 
0xC4 => "\xD0\x94", 
0xC5 => "\xD0\x95", 
0xC6 => "\xD0\x96", 
0xC7 => "\xD0\x97", 
0xC8 => "\xD0\x98", 
0xC9 => "\xD0\x99", 
0xCA => "\xD0\x9A", 
0xCB => "\xD0\x9B", 
0xCC => "\xD0\x9C", 
0xCD => "\xD0\x9D", 
0xCE => "\xD0\x9E", 
0xCF => "\xD0\x9F", 
0xD0 => "\xD0\xA0", 
0xD1 => "\xD0\xA1", 
0xD2 => "\xD0\xA2", 
0xD3 => "\xD0\xA3", 
0xD4 => "\xD0\xA4", 
0xD5 => "\xD0\xA5", 
0xD6 => "\xD0\xA6", 
0xD7 => "\xD0\xA7", 
0xD8 => "\xD0\xA8", 
0xD9 => "\xD0\xA9", 
0xDA => "\xD0\xAA", 
0xDB => "\xD0\xAB", 
0xDC => "\xD0\xAC", 
0xDD => "\xD0\xAD", 
0xDE => "\xD0\xAE", 
0xDF => "\xD0\xAF", 
0xE0 => "\xD0\xB0", 
0xE1 => "\xD0\xB1", 
0xE2 => "\xD0\xB2", 
0xE3 => "\xD0\xB3", 
0xE4 => "\xD0\xB4", 
0xE5 => "\xD0\xB5", 
0xE6 => "\xD0\xB6", 
0xE7 => "\xD0\xB7", 
0xE8 => "\xD0\xB8", 
0xE9 => "\xD0\xB9", 
0xEA => "\xD0\xBA", 
0xEB => "\xD0\xBB", 
0xEC => "\xD0\xBC", 
0xED => "\xD0\xBD", 
0xEE => "\xD0\xBE", 
0xEF => "\xD0\xBF", 
0xF0 => "\xD1\x80", 
0xF1 => "\xD1\x81", 
0xF2 => "\xD1\x82", 
0xF3 => "\xD1\x83", 
0xF4 => "\xD1\x84", 
0xF5 => "\xD1\x85", 
0xF6 => "\xD1\x86", 
0xF7 => "\xD1\x87", 
0xF8 => "\xD1\x88", 
0xF9 => "\xD1\x89", 
0xFA => "\xD1\x8A", 
0xFB => "\xD1\x8B", 
0xFC => "\xD1\x8C", 
0xFD => "\xD1\x8D", 
0xFE => "\xD1\x8E", 
0xFF => "\xD1\x8F", 
);

REPA

Функция на языке Си для конвертации строк из кодировки UTF-8 в Windows-1251 (CP1251)

Файл с функцией: https://github.com/0x1801/REPA/blob/main/utf8_2_win1251.c

  • Поставляется в виде исходного кода.
  • Написана на языке С.
  • Может быть использована в программах на языке C++.
  • Может применяться в программах для микроконтроллеров
  • Не использует ни SIMD-инструкций, ни даже x64.
  • Использует очень мало памяти: 1 массив на 32 байта (компилятор кладет его в векторный регистр, если он есть) + несколько констант.
  • Поддерживает символы utf8 до 4х байт (стандарт RFC 3629)
  • Входной массив может совпадать с выходным: данные будут перезаписаны.

Применение:

Вам ничего не понадобится, кроме текста функции и 3х макросов перед ней. Ни инклюдов и библиотек, ни массивов, никакого другого кода. Просто скопируйте ее в свой проект.

ВНИМАНИЕ: Функция требует наличия 2х лишних выделенных байтов памяти за символом конца строки во входном массиве с символами utf8. В этих байтах может лежать любой мусор. Обычно, если в вашем проекте код написан оптимально, то вы не будете каждый раз выделять память под строку. Поэтому выделить 2 лишних байта — это не проблема. Но если в вашем проекте сложно это внедрить, то можете немного самостоятельно модифицировать код.

Если есть желание проверить работу функции, можно написать тест самостоятельно или воспользоваться заготовкой из main.c: https://github.com/0x1801/REPA/blob/main/main.c

Больше main.c ни для чего не нужен.

БОНУС: в файле https://github.com/0x1801/REPA/blob/main/koi8r_2_windows1251_AVX512.c можно найти функцию конвертации из любой 8-битной ASCII-совместимой кодировки в любую 8-битную ASCII-совместимую кодировку, написанную с использованием векторных инструкций AVX512. В коде для примера реализована конвертация из koi8r в windows 1251, но алгоритм пригоден для конвертации любоых сочетаний 8-битных кодировок, совместимых с ASCII. Признаюсь честно, что сам я ее тестировать поленился, т.к. msvc 2015 «из коробки» не знает функций, которые я использовал. Функция, как минимум, компилируется (в коментарии к ней ссылка на godbolt.org). Просто мне было интересно написать функцию, которая умеет конвертировать сразу 64 символа всего за 12 инструкций (само отображение занимает при этом вообще 2 инструкции). Если вам удастся протестировать функцию или найти в ней ошибки (или улучшения), напишите мне, пожалуйста.

Связаться с автором:

Илья

chronosphere@mail.ru.

Понравилась статья? Поделить с друзьями:
0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
  • Hp designjet 500 plus драйвер windows 10 x64
  • Операционная система microsoft windows xp sp3
  • Активация windows по коду установки
  • Windows 11 просит войти в аккаунт
  • Windows phone power tools windows phone power tools