【问题标题】:How to get rid of the ".\r\n" characters appended to the error message from FormatMessageA?如何摆脱 FormatMessageA 错误消息中附加的“.\r\n”字符?
【发布时间】:2015-06-09 08:02:16
【问题描述】:

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

如果我错了,请告诉我默认的做法,而无需编写我自己的函数。 如果我是对的,请帮助我在下面的程序中格式化错误消息(取自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;
}

输出:

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

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

【问题讨论】:

  • std::string message(messageBuffer, size - 3); ?
  • 是的。我的问题是,如果我以这种方式剪切尾随字符,是否有可能丢失数据?我的意思是有什么保证我总是会收到用“。\r\n”填充的消息吗?或者我们可以通过向 FormatMessageA 提供不同的参数集来实现这一点?
  • 没有办法让FormatMessage做到这一点,你必须自己做。

标签: c++ windows boost stl


【解决方案1】:

添加以下标志正在工作;

FORMAT_MESSAGE_MAX_WIDTH_MASK (0x000000FF) : 该函数忽略常规 消息定义文本中的换行符。函数存储 将消息定义文本中的硬编码换行符写入输出 缓冲。该函数不生成新的换行符。

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

【讨论】:

  • 令人讨厌的是,即使使用FORMAT_MESSAGE_MAX_WIDTH_MASK ,虽然\r\n 已被删除,但它被替换为消息末尾的悬空空间,对于某些用例可能仍需要删除。跨度>
【解决方案2】:

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

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

【讨论】:

  • 你不必写。我已经为你做了。这就是我得到的感谢......
  • 这不是我想要的。我已经知道该怎么做了。但是,好吧,你已经为我花了一些时间。谢谢
  • 我想我的问题并不清楚。对不起,如果我冒犯了你
  • @Neo:别担心,我没有被冒犯!但我认为这是你应该这样做的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-05-07
  • 1970-01-01
  • 2021-11-30
  • 1970-01-01
  • 2020-08-04
  • 2012-11-19
  • 2013-06-14
相关资源
最近更新 更多