用c ++编写文本/二进制文件最优雅的方法是什么?

时间:2011-03-10 08:19:40

标签: c++ string file file-io text-files

我在阅读时发现了一些好的结果,例如:Read txt with iterators and preallocationread into containers。所以我想知道如何将最优雅的std :: string写入文件?

编辑:读取时我可以通过seek和tellg预先为字符串分配空间,因为我知道字符串的大小,我怎么能告诉文件系统我要写多少?

3 个答案:

答案 0 :(得分:6)

以下是关于如何输出std::string的一个小例子,但您应该真正阅读fstream

#include <iostream>
#include <fstream>
#include <string>

int main(int argc, char *argv[])
{

  std::string s("writemeout");
  std::ofstream outfile("output.txt");
  if(!outfile.is_open()) {
    std::cerr << "Couldn't open 'output.txt'" << std::endl;
    return -1;
  }

  outfile << s << std::endl;
  outfile.close();
  return 0;
}

答案 1 :(得分:1)

您可以使用operator<<函数的相应重载将字符串写入std::ofstream对象。这是一个例子:

#include <fstream>
#include <string>

int main() {
    std::string s( "Hello, World!" );
    std::ofstream f( "hello.txt" );
    if ( !f.fail() )
        f << s;
}

答案 2 :(得分:1)

主要问题是该过程没有完全逆转。

std::ofstream ofs; // presumed open
ofs << v1 << v2 << v3 << v4 << v5; // some different variables
ofs.close();

std::ifsteram ifs; // open to same stream
ifs >> r1 >> r2 >> r3 >> r4 >> r5; // variables of same types as above

您可能认为这样可行,但可能不会。写入文本流时没有正式的分隔符,您必须手动插入它们才能知道一个标记何时结束而另一个标记何时开始。

通常关于字符串,假设它们不包含换行符或没有制表符,然后在回读时,它们通常用作分隔符。

写一个字符串以便你可以阅读它的最“完美”的方法是写出它的大小然后写出它的内容。即便如此,如果你使用iostream:

os << str.size() << str;

不会在尺寸和内容之间留出任何空格,因此如果内容以数字开头,则您在以后阅读时会遇到麻烦。

os << str.size() << '\t' << str;

会奏效。

关于阅读大型集合,使用字符串最好的选择是使用制表符分隔或行分隔,并在循环中使用std :: getline。如果你的任何字符串都有空格,istream_iterator将无法工作。

您的选择是首先阅读标题部分: - 字符串数量 - 每个字符串的大小。

然后从大缓冲区读取数据,通过了解您要读取的数量及其大小,您可以预先分配缓冲区。

写二进制意味着将原始字节写入文件。这类似于C中的fwrite函数,除了你没有指定两个大小,只有一个大小,即你要写的字节数。

您需要解决以下问题: - 如果不打开二进制流,Windows将在您编写的每个ASCII 10字符前面插入一个ASCII 13字符。 - 如果您按字节顺序编写数字,请注意读取字节序和大小问题。解决此问题的最佳方法是将endian-ness放在输出的header部分中,然后以本机格式写入。假设大部分时间这将是您使用的平台,因此它更有效。

int x;
os.write( &x, sizeof(int) );

以这种方式编写数字的大好处不仅在于它在时间上更有效,而且也不需要插入任何类型的分隔符,因此阅读它们变得相对简单。

缺点是,如果文件中有任何错误,您需要一个特殊的解释器来读取文件。

无论如何,这些都是问题。

所有这一切的优雅解决方案是作为使用archive and serialize的boost库的一部分提供的。

您可以使用文本或二进制模式进行编写,它将恢复您存储它的方式。它甚至会为你“深深地”写出指针。