Win32 API:GetLastError() 和 FormatMessage() 打印垃圾

Hi-*_*gel 4 c++ winapi wine mingw character-encoding

我只是想用这个简单的代码获取最后一个错误的文本:

#include <cstdio>
#include <string>
#include <windows.h>

int main(){
    char err[256];
    memset(err, 0, 256);
    FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
                   MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err, 255, NULL);
    wprintf(L"%s\n", err); // just for the safe case
    puts(err);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

FormatMessage()尝试可能会写一些类似的东西No error,但我得到:????????? ????°??WINE 中???????  ????°?? ?????°???WinXP下在VirtualBox 中

我检查了我的每一个想法:1)在一个例子中,出于某种原因,使用了 a wchar_t,所以我尝试创建一个wchar_ts缓冲区,并将其转换为FormatMessage (否则构建失败cannot convert ‘wchar_t*’ to ‘LPSTR {aka char*}’ for argument ‘5’,2)然后我想,也许编码与 GNU/Linux 不同,所以我将 WinXP 安装到 VirtualBox 中;但是两个函数都没有给出任何可读的东西,应用程序一直在喃喃自语着自己奇怪的语言。

操作系统:Ubuntu(WINE)、WinXP(VirtualBox)。编译器:MinGW GCC

UPD:我找到了一个工作代码!

#include <cstdio>
#include <string>
#include <windows.h>

int main(){
    wchar_t err[256];
    memset(err, 0, 256);
    FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(),
                  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), err, 255, NULL);
    int msgboxID = MessageBoxW( NULL,
                                err,
                                (LPCWSTR)L"?",
                                MB_OK );
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用该-mwindows标志编译后,它会在 Ubuntu 和 WinXP 中显示一个带有可读文本的消息框。因此,问题似乎仅限于终端。

use*_*267 6

你的终端设置了错误的代码页,序列????????? 在代码页 866 中是 ????????? 在代码页 1251(即原始字节c2 fb ef ee eb ed e5 ed ee)中,通过调用更改您的终端代码页

chcp 1251
Run Code Online (Sandbox Code Playgroud)

在你运行你的应用程序之前再试一次。

至于为什么您的终端代码页与您的系统代码页不匹配是任何人的猜测,请尝试通过删除 HKCU\Console 注册表项来重置本地用户的 cmd.exe 设置(以防万一,请先备份注册表)。