Fork me on GitHub

c++之读取和写入文件

在C++中使用std::ifstream来读取文件, 使用std::ofstream来写入文件,比如txt, yaml等文件。

读取文件

方法一:

#include <string>
#include <fstream>

// 片段
std::string in_file_name;
std::ifstream file_reader(in_file_name);
if (file_reader.is_open())
{
  while (file_reader.peek() != EOF)
  {
  std::string line;
  std::getline(file_reader, line, '\n');
  std::istringstream line_reader(line);
  line_reader >> a >> b >> c;
  // do something
  }
  file_reader.close();
}
else
{
std::cerr << "Fail to open file !" << std::endl;
}
  • 使用while(!file_reader.eof())判断最后一行,该命令会把最后一行读两遍,所以使用while (file_reader.peek() != EOF)。

  • 读出来的直接是你要的类型, 而不是先以string读出来 然后转成你要的类型.

方法二:

#include <string>
#include <fstream>

//片段
std::string in_file_name;
std::ifstream file_reader(in_file_name);
if (!fs::exists(in_file_name))
{
  std::cerr << "fail to open file" << std::endl;
  return;
}
std::string line;
while(std::getline(file_reader, line))
{
  std::istringstream line_reader(line);
  line_reader >> a >> b >> c;
}
file_reader.close();

写入文件

#include <string>
#include <fstream>

std::string file_name;
std::ofstream file_writer(file_name, std::ios_base::out | std::ios_base::trunc);
if (file_writer.is_open())
{  
  file_writer << "AA" << "\t" << std::endl;
  file_writer.close();    
}
else
{
  std::cerr << "Fail to write file!" << std::endl;    
}   

实例

将tum格式的pose文件转为kitti格式的pose文件.

/*
tum pose: x y z q.x q.y q.z q.w
kitti pose: r00, r01, r02, ..., r22, t00, t10, t20
*/
#include <iostream>
#include <fstream>
#include <Eigen/Core>
#include <Eigen/Geometry>

int main(int argc, char** argv)
{
  std::string file_path = "/home/liuzhiyang/cat/pose_eva/evo/test/data/";
  // read file
  std::string in_file_name = file_path + "KITTI_02_Orb_kf.txt";
  std::ifstream file_reader(in_file_name);
  std::vector<Eigen::Matrix3d> v_r;
  std::vector<Eigen::Vector3d> v_t;
  if (file_reader.is_open())
  {
    while (file_reader.peek() != EOF)
    {
      // get pose 
      std::string line;
      std::getline(file_reader, line, '\n');
      std::istringstream line_reader(line);
      double timestamp = 0;
      line_reader >> timestamp;
      Eigen::Vector3d t;
      Eigen::Quaterniond q;
      line_reader >> t(0, 0) >> t(1, 0) >> t(2, 0) >> q.x() >> q.y() >> q.z() >> q.w();
      v_t.emplace_back(t);      
      // trans pose
      Eigen::Matrix3d r = q.normalized().toRotationMatrix();
      v_r.emplace_back(r);
    }
    file_reader.close();
  }
  else
  {
    std::cout << "fail to open file!" << std::endl;
  }

  // write file
  std::string out_file_name = file_path + "KITTI_02_orb_kf.txt";
  std::cout << out_file_name << std::endl;
  std::ofstream file_writer(out_file_name);
  if (file_writer.is_open())
  {
    for (size_t i = 0; i < v_r.size(); ++i)
    {
      Eigen::Vector3d t = v_t[i];
      Eigen::Matrix3d r = v_r[i];
      file_writer << r(0, 0) << " " << r(0, 1) << " " << r(0, 2) << " " << r(1, 0) << " " << r(1, 1) << " "
                  << r(1, 2) << " " << r(2, 0) << " " << r(2, 1) << " " << r(2, 2) << " " << t(0, 0) << " " 
                  << t(1, 0) << " " << t(2, 0) << std::endl;
    }
    file_writer.close();
  }
  else
  {
    std::cout << "fail to write file!" << std::endl;
  }
  std::cout << "save file done!" << std::endl;
  
  return 0;
}

参考

C++ fstream流的eof()函数多读一行的问题 - guoduhua的专栏 - CSDN博客
c++ - Why does ifstream.eof() not return TRUE after reading the last line of a file? - Software Engineering Stack Exchange

posted @ 2021-06-28 18:11  chrislzy  阅读(1905)  评论(0编辑  收藏  举报