【问题标题】:How to Write Strings Into Binary File如何将字符串写入二进制文件
【发布时间】:2010-10-15 15:31:39
【问题描述】:

使用此代码,我尝试将字符串“foo”打印 10 次 以二进制格式。但是为什么它的功能不起作用呢?

#include <iostream>
#include <fstream>
using namespace std;

template <typename T> void WriteStr2BinFh (string St, ostream &fn) {
     for (unsigned i = 0; i < St.size(); i++) {
         char CStr = St[i];
         fn.write(&CStr.front(), CStr.size());
     }
     return;
}

int main() {
   string MyStr = "Foo";
   ofstream myfile;
   myfile.open("OuputFile.txt", ios::binary|ios::out);

   // We want to print it 10 times horizontally
   // separated with tab

  for (int i = 0; i < 9; i++) {
      WriteStr2BinFh(Mystr+"\t", myfile);
   }

   myfile.close();   
}

【问题讨论】:

    标签: c++ binaryfiles


    【解决方案1】:

    这里有很多错误,我只是列出我看到的所有内容:

    你的 for 循环条件应该是 i

    你为什么使用模板而不是模板化参数T?

    你在 CStr 上调用了 front() 方法,但是 CStr 是一个字符,而不是一个字符串,所以我什至不知道它是如何编译的。

    假设 CStr 是一个字符串,您不想使用 & 获取 front() 迭代器的地址,而是想说:

    fn.write(St.c_str(), St.size());
    

    而且您不想循环 St.size() 迭代。只需执行上述操作。

    【讨论】:

      【解决方案2】:

      天哪,它有很多错误:

      • int main - 应该返回值;
      • 你没有在你的函数中使用模板
      • Mystr - 函数调用中的名称不正确,c++ 中的名称区分大小写;
      • char CStr - 前面没有方法,也没有 std::string;
      • 您无法获取第一个元素的地址,例如使用向量的情况;
      • 最好接受 std::string 作为 const 引用;
      • 您忘记包含字符串标题;
      • ...

      修正了你的例子,你的代码组织和你的命名:

      #include <iostream>
      #include <fstream>
      #include <string>
      
      void WriteStr2BinFh( const std::string& St, std::ostream &out ) 
      {
          out.write( St.c_str(), St.size() );
      }
      
      int main() 
      {
          std::string MyStr = "Foo";
          std::ofstream myfile( "OuputFile.txt", std::ios::binary | std::ios::out );
      
      
          for (size_t i = 0; i < 9; ++i) 
          {
              WriteStr2BinFh( MyStr+"\t", myfile );
          }
      
         myfile.close();   
         return 0;
      }
      

      但我建议使用std::fill_n 算法

      std::fill_n( std::ostream_iterator< std::string >( myfile, "\t" ), 10, MyStr );
      

      【讨论】:

      • 我喜欢 main() 中的显式返回;但是,C++ 标准确实要求从 main() 的末尾脱落以等效于返回 0。
      • 兴趣事实。我已经检查过 - 标准的第 3.6.1.5 项 - 是的,你说得对。但无论如何,我认为这应该是为了澄清。
      【解决方案3】:

      首先,char CStr 表示CStr 是单个字符。其次,fn.write(&amp;CStr.front(), CStr.size()); 把那个字符当作一个容器,就像std::vector&lt;&gt;,当然不能编译。

      假设WriteStr2BinFh 之前的一切都正常,我还没有检查过,这就是WriteStr2BinFh 应该(可能)看起来的样子:

      void WriteStr2BinFh(const string& St, ostream &fn)
      {
          for(string::iterator it = St.begin(); it != St.end(); ++it)
          {
              fn.put(*it);
          }
      }
      

      或者,最好

      void WriteStr2BinFh(const string& St, ostream &fn)
      {
          fn.write(St.c_str(), St.length());
      }
      

      【讨论】:

        【解决方案4】:

        在二进制模式下做io操作的要点:

        • 必须使用标志 ios::out(输出模式)和 ios::binary(二进制模式)以输出和二进制模式打开文件
        • 函数 write 有两个参数。第一个参数是 char* 类型,表示要写入的数据,第二个参数是 int 类型,询问要写入二进制文件的数据大小。
        • 文件最后必须关闭。

          void write_to_binary_file(WebSites p_Data)
          {
              fstream binary_file("c:\\test.dat",ios::out|ios::binary|ios::app);
              binary_file.write(reinterpret_cast<char *>(&p_Data),sizeof(WebSites));
              binary_file.close();
          }
          

          此 I/O 二进制函数将一些数据写入该函数。

        • 使用 ios::out 和 ios::binary 以输出和二进制模式打开文件。 还有一个说明符 ios::app,它告诉操作系统该文件也以附加模式打开。这意味着任何新的数据集都将附加到文件末尾。

        • 上面使用的write函数,需要参数为字符指针类型。所以我们使用类型转换器 reinterpret_cast 将结构类型转换为 char* 类型。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-06-06
          • 1970-01-01
          • 2020-08-28
          • 2016-05-08
          • 2021-10-27
          • 2016-01-15
          • 2012-09-22
          • 2016-10-03
          相关资源
          最近更新 更多