Вывод русских символов в консоль Ubuntu

Есть у меня такой код

    int main(){
        setlocale(LC_ALL, "ru");
            std::string input;
    std::set<char> letters;
    std::getline(std::cin , input);

    std::vector<std::string> wds = break_words(input);

    for(unsigned int i = 0; i < wds.size(); i++){
        std::string tmp = wds[i];
        for(unsigned int j = 0; j < tmp.size(); j++){
            letters.insert(tmp[i]);
        }
    }

    return 0;
}

break_words разбивает у меня строку на вектор строк,где одна строка - одно слово из входящей строки.

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

    std::vector<std::wstring> break_words(std::wstring input){
    std::wstringstream s(input);
    std::vector<std::wstring> out;
    const wchar_t* delim = L"., :/";
    wchar_t** tmp;
    std::wstring l;
    while(std::getline(s,l)){
        wchar_t* tk = std::wcstok(l.data(), delim,tmp);
        while(tk != nullptr){
            out.push_back(tk);
            tk = std::wcstok(nullptr,delim,tmp);
        }
    }

    return out;
}

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

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

Чтобы считать буквы, заданные в UTF-8 кодировке, нужно использовать тип wchar_t, который имеет размер 2 байта, вместо char, имеющий размер 1 байт. А также wstring вместо string.
Далее посмотреть какая локаль у вас :

user@host:~$ locale
LANG=ru_RU.UTF-8
LANGUAGE=
...

эту конкретно локаль и нужно задавать.

Далее чтобы печатать в консоль буквы в UTF-8 кодировке нельзя использовать cout,cin,... , можно только wcout,wcin,...

Ошибка неприятная у вас, вы используете неправильный индекс i, что приводит к большим проблемам. Используйте индекс длины слова j, а не количества слов.

for(unsigned int j = 0; j < tmp.size(); j++){
  // letters.insert(tmp[ i ]);
  letters.insert(tmp[ j ]);
}

Вот проверка :

# include <locale>
# include <string>
# include <set>
# include <iostream>
# include <vector>
int main(){
    char const * const l = setlocale(LC_ALL, "ru_RU.UTF-8");
    if ( l )
      std::wcout<<"l=`"<<l<<"`"<<std::endl;
            std::wstring input;
    std::set<wchar_t> letters;
    //std::getline(std::wcin , input);
    input = L"привет, мир" ;

    std::vector<std::wstring> wds = // break_words(input);
    {L"привет," , L"мир"};

    for(unsigned int i = 0; i < wds.size(); i++){
        std::wstring tmp = wds[i];
        for(unsigned int j = 0; j < tmp.size(); j++){
            letters.insert(tmp[j]);
        }
    }
    for(wchar_t c : letters){
        std::wcout<<"c=`"<<c<<"` " ;
    }
}

насчёт вашего разбиения, у вас неправильная переменная wchar * * tmp ; Надо было передавать указатель на эту переменную другого типа wchar_t * tmp ;.

wchar_t * tmp ;
..
wchar_t* tk = std::wcstok(l.data(), delim,  &  tmp);
..
tk = std::wcstok(nullptr,delim,  &  tmp);
→ Ссылка