MessageBox C++. Проблема с выводом строки

122
16 июня 2019, 01:40

Мне нужно в MessageBox запихнуть string. На выходе я получаю не нужную строку, а набор китайских иероглифов.

string str = enterStr();
wsprintf(_buffer, TEXT("%s"), str.c_str());
MessageBox(
    NULL,
    _buffer,
    TEXT("info"),
    MB_OK
);

Функция возвращает нужную строку типа string.

Answer 1

Вы печатаете юникодную (UCS-2) строку, но на вход подаете обычный ASCII. В результате у вас каждая пара ASCII символов дает символ юникода где-то в районе иероглифов. Лечится просто - печатайте ASCII, для этого достаточно в wsprintf заменить %s на %S:

wsprintf(_buffer, TEXT("%S"), str.c_str());
Answer 2

Я конечно не знаю используете ли Вы MessageBoxA (для ASCII) или MessageBoxW (для мультибайта), и что у Вас в строке, но вот этот код выводит русский текст в оконном сообщении:

#include "windows.h"
#include <string>
#include <vector>
#define SOURCE_CHARSET 65001 // UTF8
std::wstring string_to_wstring(std::string str){
    std::wstring convertedString;
    int requiredSize = MultiByteToWideChar(SOURCE_CHARSET, 0, str.c_str(), -1, 0, 0);
    if( requiredSize > 0 ){
        std::vector<wchar_t> buffer(requiredSize);
        MultiByteToWideChar(SOURCE_CHARSET, 0, str.c_str(), -1, &buffer[0], requiredSize);
        convertedString.assign(buffer.begin(), buffer.end() - 1);
    }
    return convertedString;
}
int main (){
    std::string str = "Привет, мир!";
    MessageBoxW(NULL, string_to_wstring(str).c_str(), L"Оконное сообшение", MB_OK | MB_ICONINFORMATION);
    return 0;
}

У меня IDE в UTF8 файлы сохраняет. Если что, ASCII это CP_ACP он же 0.

Answer 3

Ваш

string str = ...:
wsprintf(_buffer, TEXT("%s"), str.c_str());

это какая-то эклектическая каша из кусочков разных миров:

  • Функция wsprintf - это функция, работающая строго с широкими символами.
  • Литерал TEXT("%s") - это "полиморфный" литерал, который может быть широким или узком в зависимости от настроек проекта.
  • Параметр str.c_str() - указатель на строго узкую строку.

Что это за мешанина? Когда вы принимали решение о том, в каких символах вы будете работать, что вы решили? Узкие? Широкие? "Полиморфные"?

Если это код у вас вообще компилируется, значит вы настроили свой проект на широкие символы и прямое использование wsprintf как бы намекает, что вы решили работать именно в широких символах. Тогда причем здесь вообще TEXT("%s")? TEXT предназначен для написания "полиморфного" кода, у вас же все жестко и однозначно завязано на широкие символы. Пишите прямо L"%s" безо всяких TEXT. Этот TEXT здесь совершенно не нужен и не уместен.

Но если вы решили работать именно в широких символах, то почему тогда вы используете std::string, а не std::wstring? Используйте std::wstring и все будет работать

wstring str = ...:
wsprintf(_buffer, L"%s", str.c_str());

И только если по какой-то веской посторонней причине вам вдруг нужно скрестить ужа и ежа, т.е. использовать здесь именно std::string, то тогда спецификатор формата в wsprintf должен быть %S, а не %s

string str = ...:
wsprintf(_buffer, L"%S", str.c_str());
READ ALSO
Количество счастливых чисел

Количество счастливых чисел

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

118
Скопировать все файлы [закрыт]

Скопировать все файлы [закрыт]

Как можно скопировать все файлы, имена которых начинается с "stat" (есть примерно 500 файлов типа stat1txt stat2

165
SharedPreferences в отдельном классе

SharedPreferences в отдельном классе

Пытаюсь загрузить сохраненную строку в отдельном классе сл способом

144