2012-07-31 52 views
0

我有一个相当大的vector<string>在内存中,我想写每个string./log.txt,这里是我如何做到这一点:格式化的东西进入文件写入有效

ofstream ofs("./log.txt"); 
for (vector<string>::const_iterator cit = vec.begin(); cit != vec.end(); cit++) { 
    char buf[30]; 
    sprintf(buf, "%s\[email protected]\n", cit->c_str()); 
    ofs << buf; 
} 
ofs.close(); 

我关心的磁盘I/O次,它有效吗?更好的想法是什么?

+5

你在关心磁盘I/O。我关心公然的缓冲区溢出危险。即使这种方法比“ofs << * cit <<”--- @“;''我不会那么做。像往常一样,这种问题的答案是尝试两种方法(理智和疯狂)和时间。 YMMV – jahhaj 2012-07-31 08:28:53

+1

我一直在阅读你对你的答案的评论。你说的是需要格式化,但是你发布的代码没有格式。我想知道,你是否认为sprintf会将字符串截断为30个字符?如果是这样,你错了。试图了解问题在这里。 – jahhaj 2012-07-31 10:11:46

回答

2

这里是一个混合的想法,利用这样的事实,你并不真的需要格式化什么:

for (/* as you have */) 
{ 
    ofs.write(cit->c_str(), cit->size()); 
    ofs.write("\[email protected]", 5); 
} 
+0

对不起,我真的需要格式化。编辑 – Alcott 2012-07-31 09:02:46

+0

@Alcott:回答编辑。 – 2012-07-31 09:27:37

1

不要使用C弯路。尝试明显

ofs << *cit << "\[email protected]\n"; 

这应该比你现在有更快。我怀疑,任何合理的手动调整都可以让事情比图书馆为你做的更快。为什么上面可以假设的原因比你的代码运行得更快:

  • 一个格式化字符串没有分析
  • 没有复制到一个临时缓冲区
  • 没有找终止'\0'因为std::string就知道了其长度

最后一点不适用于"\[email protected]\n"尚;您可以将其转换为std::string以获得更多的额外性能。还有其他原因的“纯C++”的代码是更好:

  • 缓冲区溢出的任何危险
  • 嵌入在数据

磁盘I/O不应该'\0'字符没有问题一个问题,因为ofstreams被缓冲。因此,在将它们写入文件之前,实现将在内存中收集许多这些字符串。即便如此,它们可能会存储在由您的操作系统管理的缓存中,以累积更大的区块。所以磁盘应该只能看到几个巨大的写入,这非常有效。

+0

对不起,我需要格式化,发布后重新编辑。 – Alcott 2012-07-31 09:04:41

+0

@Alcott,我仍然看不需要格式化。反斜杠转义符是字符串文字的一部分,与printf无关。如果你真的需要格式化,你可能应该用C++ iostream提供,但它非常依赖于*为什么*你实际上需要格式化,即什么样的格式。 – MvG 2012-07-31 09:25:21

0

这是否高效取决于onstream的实现而不是您的代码。这是应该的。如果你需要更高效的流,你可以实现一个。

然而,正如其他人指出的,你的代码是不安全的。您应该改用C++流操作符或方法。