Изменить кодировку символа в C++

132
04 июня 2019, 15:40

Так уж пришлось, что мне нужно сделать задание в C++ builder 6. И такой вопрос, как изменить маленькую букву на большую через изменение кода символа. Так как это кириллица, функция toUpper не поможет. Пример: а - А, б - Б.

Я пробовал так, но ничего не получилось:

string symbol; 
cin >> symbol;
if (symbol == 'a') {
   symbol -= 32; 
}
cout << symbol;

Так же пробовал ставить условие

 (symbol >= 'а') && (symbol <='п')
Answer 1

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

Вот пример ближе к вашему вопросу:

// locale::locale
#include <iostream>       // std::cout
#include <locale>         // std::locale
#include <stdexcept>      // std::runtime_error
int main ()
{
    std::locale loc;     // initialized to locale::classic()
    try {
        loc = std::locale ("Russian");
        std::string s = "ыыыыы";
        for (auto& c:s)
            c = std::toupper(c, loc);
        std::cout << s << '\n';
    }
    catch (std::runtime_error) {
        loc = std::locale (loc, "", std::locale::ctype);
    }
    std::cout << "The selected locale is: " << loc.name() << '\n';
    return 0;
}

UPD

При установке локализации (Подробнее здесь) нужно понимать какая кодировка попадает на вход. Если это внешние данные, то нужно знать в какой кодировке они поступают. Например, при вводе с консоли это может быть 866(OEM) страница, а программа ожидает 1251(ANSI). Для этого нужно явно указать кодировку. Например:

loc = std::locale ("Russian_Russia.866");
Answer 2

Пример для латиницы, но для кириллицы тоже будет работать.
Я делаю так, хотя меня за это и ругают некоторые граждане.
Может быть кому-то кажется, что это не очень красиво, зато решение на 101% портабельное.
Будет работать на всех кодировках, и на ASCII, и на EBCDIC и на любой другой.
Для кириллицы будет работать и на КОИ и на CP1251 и на Юникоде.

char my_to_upper(char ch){
char retchar;
switch(ch){
case 'a':retchar='A';break;
case 'b':retchar='B';break;
case 'c':retchar='C';break;
case 'd':retchar='D';break;
case 'e':retchar='E';break;
case 'f':retchar='F';break;
case 'g':retchar='G';break;
case 'h':retchar='H';break;
case 'i':retchar='I';break;
case 'j':retchar='J';break;
case 'k':retchar='K';break;
case 'l':retchar='L';break;
case 'm':retchar='M';break;
case 'n':retchar='N';break;
case 'o':retchar='O';break;
case 'p':retchar='P';break;
case 'q':retchar='Q';break;
case 'r':retchar='R';break;
case 's':retchar='S';break;
case 't':retchar='T';break;
case 'u':retchar='U';break;
case 'v':retchar='V';break;
case 'w':retchar='W';break;
case 'x':retchar='X';break;
case 'y':retchar='Y';break;
case 'z':retchar='Z';break;
default: retchar=ch;break;
}
return retchar;
}

UPD1:

В большинстве случаев для кириллицы это не будет работать, т.к. буквы в большинстве случаев занимают > 1 байта, а размер char в большинстве случаев равен 1 байту – Tocic 5 минут назад

Не, ну для Юникода, конечно, надо брать тип wchar_t.
Если входной символ wchar_t, то и выходной символ, естественно, тоже будет wchar_t.
Идея в том, что схема со switch работать будет и для всех типов символов (в том числе и для wchar_t), и для всех кодировок.
В конце концов, если уж быть пуристом, можно сделать шаблон.

template <class T> T my_to_upper(T ch){
    T retchar;
    switch(ch){
    case 'a':retchar='A';break;
    case 'b':retchar='B';break;
    case 'c':retchar='C';break;
    case 'd':retchar='D';break;
    case 'e':retchar='E';break;
    case 'f':retchar='F';break;
    case 'g':retchar='G';break;
    case 'h':retchar='H';break;
    case 'i':retchar='I';break;
    case 'j':retchar='J';break;
    case 'k':retchar='K';break;
    case 'l':retchar='L';break;
    case 'm':retchar='M';break;
    case 'n':retchar='N';break;
    case 'o':retchar='O';break;
    case 'p':retchar='P';break;
    case 'q':retchar='Q';break;
    case 'r':retchar='R';break;
    case 's':retchar='S';break;
    case 't':retchar='T';break;
    case 'u':retchar='U';break;
    case 'v':retchar='V';break;
    case 'w':retchar='W';break;
    case 'x':retchar='X';break;
    case 'y':retchar='Y';break;
    case 'z':retchar='Z';break;
    default: retchar=ch;break;
    }
    return retchar;
    }

UPD2:

Для кириллицы в кодировке CP1251 (которая как раз используется в Борланд 6.0 Билдер), будет работать и вариант с char.

UPD3:

Ваш код для char можно записать как return symbol < 65 || symbol > 122 ? symbol : ((char)(((int)symbol) + 32)); – LLENN 10 секунд назад

Это будет работать для кодировки ASCII. Но, к примеру, для кодировки EBCDIC это работать не будет.

UPD4:

@pepsicoca1 '...' - это литерал типа char – Tocic 10 минут назад

Правильно, но на этот случай у нас есть switch с винтом.

wchar_t my_to_upper(wchar_t ch){
wchar_t retchar;
switch(ch){
case L'a':retchar=L'A';break;
case L'b':retchar=L'B';break;
case L'c':retchar=L'C';break;
case L'd':retchar=L'D';break;
case L'e':retchar=L'E';break;
case L'f':retchar=L'F';break;
case L'g':retchar=L'G';break;
case L'h':retchar=L'H';break;
case L'i':retchar=L'I';break;
case L'j':retchar=L'J';break;
case L'k':retchar=L'K';break;
case L'l':retchar=L'L';break;
case L'm':retchar=L'M';break;
case L'n':retchar=L'N';break;
case L'o':retchar=L'O';break;
case L'p':retchar=L'P';break;
case L'q':retchar=L'Q';break;
case L'r':retchar=L'R';break;
case L's':retchar=L'S';break;
case L't':retchar=L'T';break;
case L'u':retchar=L'U';break;
case L'v':retchar=L'V';break;
case L'w':retchar=L'W';break;
case L'x':retchar=L'X';break;
case L'y':retchar=L'Y';break;
case L'z':retchar=L'Z';break;
default: retchar=ch;break;
}
return retchar;
}
READ ALSO
Ошибка в передаче аргумента в функцию

Ошибка в передаче аргумента в функцию

Есть ошибка, cmap передается в такую фукнцию

130
Не работает fstream C++

Не работает fstream C++

Изучаю работу с файлами в С++ Сделал абсолютно все как в примереВ консоль выводится сообщение Good!, но при этом файл не создается, а если вручную...

158
Проблема с заменой в com порте

Проблема с заменой в com порте

Такая проблема, есть команда которая вводится в cmd:

153
winapi русские символы на кнопке

winapi русские символы на кнопке

Есть кнопка, создающаяся следующим кодом:

143