【问题标题】:How do I check if string::append() is going to fail如何检查 string::append() 是否会失败
【发布时间】:2015-12-20 13:54:05
【问题描述】:

我正在编写一个代码,我需要在其中添加数据来创建std::string(这里的数据是指应用程序的日志)。但是字符串也有其大小的限制。我已经在try-catch 块中编写了代码,当append() 失败时,它会抛出异常。我需要在append() 之前检查是否附加新字符串会导致任何exception,因为一旦抛出异常,它会清除字符串中的数据。
我想检查附加新字符串是否会导致任何异常,如果是,则将数据写入文件并清除字符串以供下次输入。
因为它是一个应用程序日志,我不知道最终的大小是多少。所以我试图让代码更不容易受到上述问题的影响。
我检查了一个条件如下:
如果是“current_string_size + to_be_attached_string_size exceeds string.max_size()”,则将代码写入文件。
如果“不是”,则将 to_be_attached_string 附加到 current_string。
但它在某个地方失败了。
我需要检查什么条件?

【问题讨论】:

  • 但它在某处失败了在什么意义上?你能提供一个最小的复制代码吗? string::max_size() 通常很大...
  • 我们在谈论std::basic_string::max_size()std::basic_string::append() 吗?前者通常不需要担心,而后者从 C++11 开始就有强大的异常安全保证。
  • 在写出日志之前尝试填满所有 RAM 不是一个好主意 - 您可能会面临操作系统内存不足的例程开始终止应用程序的风险,或者由于内存过度使用而导致崩溃,以及更多定期写入日志内容可能是检查程序是否仍然运行正常和/或帮助调试崩溃的有用方法。最多将大约 16kb 的内容缓冲到文件中,然后将 write 缓冲到文件中 - 远远超过这不太可能显着提高性能。
  • @Walter:我写过类似的代码:string strData; void fun(input_string) { try { if ((strData.size() + input_string_size) >= strData.max_size()) { // 将 strData 写入文件并清除 strData 以供下次输入。返回; } strData.append(input_string); } 捕捉(异常 e){ 返回; } }
  • @SamL - max_size() 非常没用,因为它只是为您提供了理论大小的上限。分配更多将总是抛出异常。如果你的程序中有其他一些数据结构,通常你甚至无法接近这个值。

标签: c++ windows string exception append


【解决方案1】:

使用 C++11 并简单地将您的 string::append() 尝试放入 try catch(就像您最初所做的那样)。 If an exception is thrown for any reason, this function has no effect (strong exception guarantee),与您的观点相反(“一旦抛出异常,它就会从字符串中清除数据”)或 C++11 之前的版本。

std::string orig, to_append;
try {
  orig.append(to_append);
} catch(...) {
  write_to_file(orig);
  orig = std::move(to_append);
}

但是,将日志写入string 是没有意义的(除非您想在同一程序中从该string 中读取,但这不再是日志)。 根据Peter Eke 的建议,直接写信给std::ofstream 更有意义:

void add_to_log(std::string const&msg, bool flush=false)
{
  static std::ofstream logfile;
  if(!logfile)
    logfile.open("logfile.txt");
  logfile << msg;
  if(flush) logfile << std::flush;
}

std::ofstream 无论如何都会缓冲输出,即仅当缓冲区已满或强制写入磁盘时才写入磁盘(通过flush)。

【讨论】:

  • 所以你的意思是,我应该使用std::ofstream 而不是std::string?如果是,那么将数据存储到std::ofstream 中是否有任何内存限制,例如std::string?如果有限制,那么同样的问题会再次出现。在这里我需要检查std::ofstream 是否已满。如果已满,则写入文件。
  • Sam,std::ofstream 写入文件,它不能是满的(除非你的光盘是满的,但是你无论如何都不能做任何输出......)。
猜你喜欢
  • 2014-01-30
  • 1970-01-01
  • 2016-09-17
  • 1970-01-01
  • 2016-08-08
  • 2017-01-02
  • 2011-12-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多