C++. Проблемы с кодировкой кириллицы в массиве char

Столкнулся с проблемой. У меня раздвоенная кодировка.

SetConsoleOutputCP(1251);
    SetConsoleCP(1251);

Когда ввожу массив через консоль cin>>MassChar; он принимает кодировку, где 1 символ хранится в 1-м элементе. Для слова "Привет" требуется массив размером минимум 7 элементов. Когда я присваиваю значение в коде char MassChar[]="Привет";, то для 1 символа требуется 2 элемента и при выводе одного элемента массива выводит М или О. Для слова "Привет" требуется массив размером минимум 13 элементов. Как мне сделать, чтобы всё было как в первом случае (1 символ = 1 элемент). Сразу говорю: wchar_t и char16_t предлоть не надо.


Ответы (2 шт):

Автор решения: Lith

Длина вектора 13 символов т.к. каждый не-ASCII символ использует 2 байта, 6*2=12 (Привет), последний символ \0 нуль обозначающий конец строки. Можно сделать свой класс для данного случая и перегрузить оператор индексирования.

    #include <iostream>
    #include <fstream>
    #include <string>
    #include <Windows.h>
    class Utf8String {
    public:
        Utf8String(const std::string& str) : data(str) {}
    
        std::string operator[](size_t index) const {
            return getCharacterAt(index);
        }
    
        size_t length() const {
            return countCharacters();
        }
    
    private:
        std::string data;
    
        size_t countCharacters() const {
            size_t count = 0;
            for (size_t i = 0; i < data.size(); ) {
                if ((data[i] & 0x80) == 0) {
                    i += 1;
                }
                else if ((data[i] & 0xE0) == 0xC0) {
                    i += 2;
                }
                else {
                    throw std::runtime_error("Неправильная последовательность UTF-8.");
                }
                count++;
            }
            return count;
        }
    
        std::string getCharacterAt(size_t index) const {
            size_t count = 0;
            for (size_t i = 0; i < data.size(); ) {
                if ((data[i] & 0x80) == 0) {
                    if (count == index) return data.substr(i, 1);
                    i += 1;
                }
                else if ((data[i] & 0xE0) == 0xC0) {
                    if (count == index) return data.substr(i, 2);
                    i += 2;
                }
                else {
                    throw std::runtime_error("Неправильная последовательность UTF-8.");
                }
                count++;
            }
            throw std::out_of_range("Индекс вне границ вектора символов.");
        }
    };
    
    
    
    int main() {
        SetConsoleOutputCP(65001);
        SetConsoleCP(65001);
        const char* charArray = "Привет";
        Utf8String MassChar(charArray);
    
        std::cout << "Первый символ строки: " << MassChar[0] << std::endl;
    
        std::cout << "Длина строки: " << MassChar.length() << std::endl;
    
        std::cout << "Полная строка: " << MassChar[0] << MassChar[1] << MassChar[2] << MassChar[3] << MassChar[4] << MassChar[5] << std::endl;
    
        char userInput[2 * 6 + 1];
        std::cout << "Введите новую строку: ";
        std::cin >> userInput;
    
        Utf8String userUtf8Input(userInput);
        std::cout << "Вы ввели: " << userUtf8Input[0] << userUtf8Input[1] << userUtf8Input[2] << std::endl;
    
        return 0;
    }

Вывод будет в консоли:

Первый символ строки: П
Длина строки: 6
Полная строка: Привет
Введите новую строку: Мир
Вы ввели: Мир

Кодировка файла 65001.

→ Ссылка
Автор решения: Лучший Шиномантаж

Если вам нужно просто присвоить значение "Привет", то можно сделать так char MassChar[7]{'П','р','и','в','е','т'};, либо char MassChar[]{'П','р','и','в','е','т','\0'};(если вы не указываете размер массива, то без \0 в конце у вас может вывести cout <<MassChar;, что-то по типу "приветММММММММММММММММММММММММММММММРНZч"). 1 символ = 1 элемент.

→ Ссылка