Win32 API: GetLastError() with FormatMessage() prints a junk

Hi-Angel picture Hi-Angel · Aug 13, 2014 · Viewed 10.5k times · Source

I'm just trying to get a text of the last error with this simple code:

#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;
}

FormatMessage() tries probably to write something like No error, but instead I getting: ┬√яюыэхэю єёях°эю in WINE, and ╬яхЁрЎш  єёях°эю чртхЁ°хэр under WinXP in VirtualBox.

I checked every idea I've had: 1) in an example, for some reason, a wchar_t is used, so I tried creating a buffer of wchar_ts, and casting it for FormatMessage (otherwise build fails with cannot convert ‘wchar_t*’ to ‘LPSTR {aka char*}’ for argument ‘5’), 2) then I thought, perhaps encoding differs from the GNU/Linux one, so I installed WinXP into VirtualBox; but none of two functions gave anything readable, app keeps mumbling its own weird language.

OS: Ubuntu(WINE), WinXP(VirtualBox). Compiler: MinGW GCC

UPD: I found a working code!

#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;
}

Upon compiled with the -mwindows flag, it shows up a message box with readable text in both Ubuntu and WinXP. So, the problem looks to be terminal-only.

Answer

user657267 picture user657267 · Aug 13, 2014

Your terminal is set to the wrong code page, the sequence ┬√яюыэхэю in code page 866 is Выполнено in code page 1251 (i.e. the raw bytes c2 fb ef ee eb ed e5 ed ee), change your terminal code page by calling

chcp 1251

before you run your app and try again.

As to why your terminal code page does not match your system code page is anyone's guess, try resetting the cmd.exe settings for the local user by deleting the HKCU\Console registry key (make a registry backup first just in case).