isalnum и кирилица [закрыт]

109
19 февраля 2021, 01:10
Закрыт. Этот вопрос не по теме. Ответы на него в данный момент не принимаются.

Хотите улучшить этот вопрос? Обновите вопрос так, чтобы он вписывался в тематику Stack Overflow на русском.

Закрыт 1 год назад.

Улучшить вопрос

Пытаюсь в своем проэкте считать кирилицу:

bool Helper::IsAllNum(char symbol)
{
    if (isalpha(symbol))
    {
        return false;
    }
    return true;
}
std::string Helper::CheckItem(std::string & word)
{
    if (!word.empty())
    {
        while (IsAllNum(word.back()))
        {
            word.pop_back();
        }
    }
    return word;
}

Читал, советуют использовать unsigned, но это только помогает для пробелов и islower - toupper, пытался проверить вот так:

for (int i = 0; i < 256; ++i)
    {
        if (isalnum((unsigned char)i))
        {
            cout << i << "   " << char(i) << "\n";
        }
    }

без результатно, что посоветуете сделать?

Идея в том, что мне нужно спарсить файл, я получаю слово в конце с запятыми и т.п., нужно проверить, что бы небыло ничего лишнего в конце строки и записать слово в map. С англ. работает идеально, с русским не как.

Answer 1

isalnum проверяет, является ли символ буквой или цифрой в текущей локали.

Для того, чтобы выставить русскую локаль нужно воспользоваться функцией std::setlocale

Answer 2

Во-первых, в isalnum нельзя передавать char, т.к. у русских символов будут отрицательные значения, а функция isalnum принимает только значения в диапазоне 0-255 или EOF.

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

В-третьих кодировка файла должна быть однобайтовой, т.к. isalnum принимает только один символ, и не может работать с UTF-8.

Локаль устанавливается функцией setlocale.

#include <cctype>
#include <clocale>
#include <iostream>
int main() {
    setlocale(LC_ALL, "ru_RU.cp1251");
    char c = '\xfe';  // 'ю' in cp1251
    bool alnum = isalnum(static_cast<unsigned char>(c));
    std::cout << "isalnum=" << alnum << "\n";
}

При этом локаль должна быть установлена в системе, например на линуксе это выглядит так:

$ locale -a
C
C.UTF-8
POSIX
en_US.utf8
$ ./a.out 
isalnum=0

-- не работает.

Устанавливаем локаль

$ sudo localedef --no-archive -c -i ru_RU -f CP1251 ru_RU.CP1251
$ locale -a
C
C.UTF-8
POSIX
en_US.utf8
ru_RU.cp1251
$ ./a.out 
isalnum=1

-- работает.

Answer 3

Для того, чтобы изменить кодировку используйте либо заголовочный файл windows.h и следующие две строки кода в начале функции main

 SetConsoleCP(1251);
 SetConloleOutputCP(1251);
 // Остальной код

Либо заголовочный файл clocale и строку кода

  char *locale = setlocale(LC_ALL, ""); 

Также можно воспользоваться этой командой если у вас к примеру английская версия ОС

  char *locale = setlocale(LC_ALL, "RUSSIAN"); 

Для чтения данных из файла в C++ используется класс ifsteam. Нужно создать объект этого класса и помощью него считать данные (побайтово или построчно). Для побайтового считывания:

 ifstream fin;
 fin.open ("Путь к файлу");
 // проверяем удалось ли открыть файл
 if (!fin.is_open){
 cout << "ошибка открытия файла";
 } 
 else {
 cout << "Файл успешно открыт";
 char ch;
 while (fin.get(ch)){
 // Далее в цикле нужно проверить является ли данный символ русской буквой.
 int char_code = (int)ch;
 // Будем проверять код каждой буквы согласно ANSI-таблице
 if (char_code >=127 && char_code <=255){
 // Далее нужно обработать файл с помощью объекта класса ofstream
 } 
 }
 }
READ ALSO
заменить дублирующиеся байты

заменить дублирующиеся байты

Есть последовательность байтов, которая может содержать определенные пары байтовНадо эти пары найти и заменить на одинарные

128
Перемещение содержимого файла

Перемещение содержимого файла

Необходимо организовать перемещение содержимого файла блокамиНапример скопировать первые 20 байт в другой файл, а в исходном их удалить

112
Создать QIODevice (QSerialPort) в отдельном потоке

Создать QIODevice (QSerialPort) в отдельном потоке

Класс QSerialPort, насколько я понимаю, не предназначен для работы с QThreadПоэтому делаю класс наследник который сможет работать с QThread, в котором...

148
map перезаписывает элемент а не добавляет

map перезаписывает элемент а не добавляет

Метод map перезаписывает элемент а не добавляет новый, пробовал и методом emplace и pair, в чем ошибка подскажите?

113