How to get rid of the ".\r\n" characters appended to the error message from FormatMessageA?

1.2k views Asked by At

I'm replacing boost::system::error_code with std::errc. The error_code supports displaying the error message in string format through error_code::message(). But I think in STL, we don't have a pre-defined way to do it. Am I right?

If I'm wrong, please tell me the default way of doing it without writing my own function. If I'm right, please help me in formatting the error message in the below program (taken from stackoverflow)

//Returns the last Win32 error, in string format. Returns an empty string if there is no error.
std::string GetLastErrorAsString()
{
    //Get the error message, if any.
    DWORD errorMessageID = ::GetLastError();

    LPSTR messageBuffer = nullptr;
    size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);

    std::string message(messageBuffer, size);

    //Free the buffer.
    LocalFree(messageBuffer);

    return message;
}

int main()
{
    SetLastError((DWORD)std::errc::operation_canceled);

    string str(GetLastErrorAsString());
    cout << "str = " << str;
    return 0;
}

Output:

str = The previous ownership of this semaphore has ended.\r\n

The output of boost::system::error_code::message() doesn't have these extra ".\r\n". Is there anyway by tweaking the parameters provided to FormatMessageA(), we can get rid of these extra letters? Or do I have to cut myself (simply removing trailing 3 characters)? If I just blindly cut them, Is there any chance, the error message comes without these characters?

2

There are 2 answers

4
TonyK On BEST ANSWER

Here, I've done all the hard work for you:

while (size && isspace (messageBuffer[size-1]))
    messageBuffer[--size] = 0;
if (size && messageBuffer[size-1] == '.')
    messageBuffer[--size] = 0;
1
yunus celik On

Adding following flag is working;

FORMAT_MESSAGE_MAX_WIDTH_MASK (0x000000FF) : The function ignores regular line breaks in the message definition text. The function stores hard-coded line breaks in the message definition text into the output buffer. The function generates no new line breaks.

std::string GetLastErrorAsString()
{
    //Get the error message, if any.
    DWORD errorMessageID = ::GetLastError();

    LPSTR messageBuffer = nullptr;
    size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK,
        NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);

    std::string message(messageBuffer, size);

    //Free the buffer.
    LocalFree(messageBuffer);

    return message;
}

int main()
{
    SetLastError((DWORD)std::errc::operation_canceled);

    string str(GetLastErrorAsString());
    cout << "str = " << str;
    return 0;
}