C++笔记(4) - 将数据写入文档的方法(在文档末尾写入数据)

使用流操作的方法实现

在进行开发的过程中,有时候光通过终端看输出的数据比较费劲,无法事后进行对比分析等操作。所以需要将数据写入文档中,方便后续使用。

实现步骤:

1. 首先需要包含头文件#include <fstream>

2. 声明类用于读取、写入数据

ofstream         //文件写操作 内存写入存储设备 
ifstream         //文件读操作,存储设备读取到内存中
fstream          //读写操作,对打开的文件可进行读写操作 

在这两个对象中,ofstream::open或ifstream::open是打开文件的函数,该函数默认以out或in的方式读入或写出,这两种方式都会先清空文件中的数据,如果想在上一次执行该操作的文件后加入数据,那么就要用ios类中的app方法,ios:app(后面有具体的不同指令含义的介绍)
ios::app:打开文件不会清空数据,文件指针始终在文件尾,因此只能在文件尾写数据。
利用这一点就可以实现添加数据到文件尾的方法

打开文件的方式在ios类(所以流式I/O的基类)中定义,有如下几种方式:

指令作用
ios::in为输入(读)而打开文件
ios::out为输出(写)而打开文件
ios::out为输出(写)而打开文件
ios::ate初始位置:文件尾
ios::app所有输出附加在文件末尾
ios::trunc如果文件已存在则先删除该文件
ios::binary二进制方式

这些方式是能够进行组合使用的,以“或”运算(“|”)的方式:例如

ofstream out;
out.open("Hello.txt", ios::in|ios::out|ios::binary)     //根据自己需要进行适当的选取

举例:下面这个代码是我在开发ros程序时候用的

#include <fstream>
#include <iostream>

# define class_num 20
void depth_callback(const darknet_ros_msgs::BoundingBoxes::ConstPtr& detect_msg, const sensor_msgs::Image::ConstPtr& msg)
{
    int u[class_num] = {};
    int v[class_num] = {};
    int centerIdx[class_num] = {};
    int temp1[class_num] ={};
    int temp2[class_num] ={};
    int temp3;

    int sizes = msg->data.size();

    float* depths = (float*)(&msg->data[0]);
   
    int num = detect_msg->bounding_boxes.size();
    // 看一下视频的宽度
    temp3 = msg->width;
    for (int i = 0; i < num; i++)
    {
        // 看一下输出的数据是否为负数
        temp1[i] = (detect_msg->bounding_boxes[i].xmax - detect_msg->bounding_boxes[i].xmin)/2;
        temp2[i] = (detect_msg->bounding_boxes[i].ymax - detect_msg->bounding_boxes[i].ymin)/2;

        u[i] = ((detect_msg->bounding_boxes[i].xmax - detect_msg->bounding_boxes[i].xmin)/2) + detect_msg->bounding_boxes[i].xmin; 
        v[i] = ((detect_msg->bounding_boxes[i].ymax - detect_msg->bounding_boxes[i].ymin)/2) + detect_msg->bounding_boxes[i].ymin;
        centerIdx[i] = u[i] + msg->width * v[i];
        if (centerIdx[i] < 0) 
        {
            centerIdx[i] = 0;
        }
        else if (centerIdx[i] > sizes /4)
        {
            centerIdx[i] = sizes /4;
        }
    }
    std::cout<<"Bouding Boxes (header):" << detect_msg->header <<std::endl;
    std::cout<<"Bouding Boxes (image_header):" << detect_msg->image_header <<std::endl;
    std::cout<<"Bouding Boxes (Class):" << "\t";
    std::ofstream write;
    write.open("result-test.csv", std::ios::app);
    for (int i = 0; i < num; i++)
    {
        std::cout << detect_msg->bounding_boxes[i].Class << "\t";
        std::cout<<"Center distance :  " << depths[centerIdx[i]] << "  m" << std::endl;
        std::cout<<"temp1 :  " << i << ":    " << temp1[i] << std::endl;
        std::cout<<"temp2 :  " << i << ":    " << temp2[i] << std::endl;
        std::cout<<"temp3 :  " << temp3 << std::endl;
        write << i << ","<<"中心点位置" <<","<< centerIdx[i] << ","<< "temp1"<<","<<temp1[i]<<"," <<"temp2"<<","<<temp2[i]<<","<<"temp3"<<","<< temp3<<","<<"x"<<","<<u[i]<<","<<"y"<<","<<v[i]<< std::endl;          
    }
    write.close();
    std::cout << "\033[2J\033[1;1H";     // clear terminal    
}

输出结果如下:

在这里插入图片描述
-------------------------------------------------------------更新:2020.08.05-------------------------------------------------------------

新增操作,每次执行前先清空这个文档的方法

本文开始讲的方法可以完成在循环执行的程序中实现在末尾添加新的内容,但是如果这个程序执行了两遍,那么这个文档中的数据就是两次运行得到数据的总和。如果我们想每次运行这个程序的时候都是得到一个新的数据,并且还不想更改这个csv文件的名字,那么可以在程序中添加一个初始化的操作。
在执行回调函数的开始先执行下面这段代码即可完成上述功能。

// 在进入回调函数的时候添加这段代码
ofstream clearfile; //每次打开的时候先将文件内容清空
clearfile.open("result-test.csv", ios::out | ios::trunc );
clearfile.close();

这段代码实际上就是用了ios::trunc的功能:如果文件已存在则先删除该文件,这样就可以在每次执行程序的时候都是一个新的文件。并且名字还是原来的名字。

参考

C++中将数据添加到文件的末尾
C++文件读写详解(ofstream,ifstream,fstream)

  • 3
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值