如何摆脱 FormatMessageA 错误消息中附加的“.\r\n”字符?

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

我将 boost::system::error_code 替换为 std::errc。 error_code支持通过error_code::message()以字符串格式显示错误信息。但我认为在 STL 中,我们没有预先定义的方法来做到这一点。我说的对吗?

如果我错了,请告诉我不用自己写函数的默认方法。 如果我是对的,请帮助我格式化以下程序中的错误消息(取自 Whosebug)

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

输出:

str = 此信号量的先前所有权已结束。\r\n

boost::system::error_code::message() 的输出没有这些额外的“.\r\n”。无论如何,通过调整提供给 FormatMessageA() 的参数,我们是否可以摆脱这些额外的字母?或者我必须削减自己(只需删除尾随的 3 个字符)?如果我只是盲目地剪掉它们,有没有可能出现没有这些字符的错误消息?

在这里,我已经为你完成了所有辛苦的工作:

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

正在添加以下标志;

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