当前位置: 首页 > news >正文

怎么自己建立一个网站后台/深圳今天重大事件新闻

怎么自己建立一个网站后台,深圳今天重大事件新闻,模版营销型网站怎么做,58同城找工作 招聘编程基础(2):文件读写前言一、C文件读写(基于文件指针)1.基本概念与主要使用函数2.光束法平差文件读取使用案例二、C文件读写(基于文件流)总结前言 专门列出一章文件读写,主要是因为…

编程基础(2):文件读写

  • 前言
  • 一、C++文件读写(基于文件指针)
    • 1.基本概念与主要使用函数
    • 2.光束法平差文件读取使用案例
  • 二、C++文件读写(基于文件流)
  • 总结


前言

专门列出一章文件读写,主要是因为之前的知识较为零散,想汇总起来以供参考。本文在初稿撰写时只加入了较为简单的C++标准下文件读写,后续会加入较为复杂的目录寻找等Python标准下的写作规范。


提示:以下是本篇文章正文内容,下面案例可供参考

一、C++文件读写(基于文件指针)

1.基本概念与主要使用函数

提到文件读写,较为简单并且基本够用的做法是使用一下四个函数:
(1)FILE *fp = fopen(filename.c_str(),_mode);
(2)int succeed = fscanf(FILE *fp,const string format,T *value);
(3)int succeed = fprintf(FILE *fp,const string format,T *value);
(4)fclose();
——————————
这个里面最重要的是中间的fscanf和fprintf。最初的fopen函数是打开了一个文件流。fscanf函数则是读入数据的主力,它搜索文件流中符合format形式的数据,赋值给value对应的指针,该函数遇到空格和换行就停止。fprintf函数是将value指针中存储的数据,按照format的形式,加入到输出文件流中,需要手动的添加换行符。因此,我们配合指针、数组,即可完成数据的读写。顺便说一下,笔者刚开始十分疑惑为什么一个文件读写的函数,会有一个int类型的返回值。其实这是有编程哲学的,这个函数返回的int值统计了数据被正确赋值到变量的个数,这对我们查找程序中的问题很有帮助。此外,很多函数写作的时候往往是bool类型,甚至直接就被写成void类型,因为这些函数的功能往往是对数据进行操作(一定要引用传递哦,否则会报“段错误:核心已转储”,经历过的人都懂),很难给出一个具体的返回值。对于这些函数来说,返回值的意义已经不大了,主要是为了查找问题,例如设定一个bool的函数,检查是否所有的数据都处理完毕,如果有问题的话,就返回False。

2.光束法平差文件读取使用案例

下面来看一个案例,完成对光束法平差文件的读写。该文件的基本数据结构如下:
在这里插入图片描述
光束法平差记录了相机、物方坐标点和投影的关系。这种文件一般有一个文件头,第一行是三个统计量,分别是相机总数、点号总数以及总参数量。接下来是每个物方点的经过某个相机投影后的像点坐标,刻画了投影关系,一行4个数据,总共nPoints行。而后是相机参数,一列9个为一组,记录了3个旋转角、3个平移量、1个焦距和两个2个变参数,共有nCameras组。最后是所有物方点的信息,一列3个为一组,分别为XYZ点,共有nPoints组。
——————————————
我们的目标是,读取这个文件,并且将相机参数、点以及参数存储进列表。
为了能够让我们的程序适应不同的BA问题(对应不同的BA数据文件),我们定义了一个BALProblem类,使用其成员变量来存储数据(这是一个非常常见的编程技巧),并在构造函数中读取文件、初始化成员变量。在这个类的最外面,设置一个检测机制的模板函数FscanOrDie(),通过其返回值判断文件读取是否有异常出现:代码如下(示例):

template<typename T>
void FscanOrDie(FILE *fptr,const char* format,T*value){int n_read = fscanf(fptr,format,value);if(n_read!=1){std::cerr << "Invalid UW data file. ";}
}class BALProblem{
public:BALProblem(const string filename){FILE *fp = fopen(filename.c_str(),'r');FscanfOrDie(fp,"%d",&m_nCameras);FscanfOrDie(fp,"%d",&m_nPoints);FscanfOrDie(fp,"%d",&m_nObservations);//注意,这里一定要是指针std::cout << "Header: " << m_nCameras<< " " << m_nPoints<< " " << m_nObservations;//根据观测值数量记录相机编号和点编号列表camera_index_ = new int[m_nObservations];point_index_ = new int[m_nObservations];observations_ = new double[2 * m_nObservations];//读取数据for(int i=0;i<m_nObservations;++i){FscanfOrDie(fp,"%d",&camera_index_[i]);//或camera_index_+iFscanfOrDie(fp,"%d",&point_index_[i]);for(int j=0;j<2;++j){FscanfOrDie(fp,"%lf",observation_+2*i+j);}}m_nParameters = 9 * m_nCameras + 3 * m_nPoints;parameters_ = new double[m_nParameters];for(int p=0;p<m_nParameters;++p){FscanfOrDie(fp,"%lf",parameters_+p);//统一管理所有的参数}}
private:int m_nCameras;int m_nPoints;int m_nObservations;int m_nParameters;int *camera_index_;int *point_index_;double *observations_;double *parameters_;
};

注意fscanf赋值的必须是指针。下面给出写文件的代码:

void BALProblem::WriteToFile(const std::string &filename) const {FILE *fptr = fopen(filename.c_str(), "w");if (fptr == NULL) {std::cerr << "Error: unable to open file " << filename;return;}fprintf(fptr, "%d %d %d %d\n", m_nCameras, m_nCameras, m_nPoints, m_nObservations);for (int i = 0; i < m_nObservations; ++i) {fprintf(fptr, "%d %d", camera_index_[i], point_index_[i]);for (int j = 0; j < 2; ++j) {fprintf(fptr, " %g", observations_[2 * i + j]);}fprintf(fptr, "\n");}for (int i = 0; i < num_cameras(); ++i) {double angleaxis[9];if (use_quaternions_) {//OutPut in angle-axis format.QuaternionToAngleAxis(parameters_ + 10 * i, angleaxis);memcpy(angleaxis + 3, parameters_ + 10 * i + 4, 6 * sizeof(double));} else {memcpy(angleaxis, parameters_ + 9 * i, 9 * sizeof(double));}for (int j = 0; j < 9; ++j) {fprintf(fptr, "%.16g\n", angleaxis[j]);}}const double *points = parameters_ + camera_block_size() * num_cameras_;for (int i = 0; i < num_points(); ++i) {const double *point = points + i * point_block_size();for (int j = 0; j < point_block_size(); ++j) {fprintf(fptr, "%.16g\n", point[j]);}}fclose(fptr);
}

这个类中还给出了对外定义的get数据接口,这里就不再赘述了。结合fscanf函数和fprintf函数,以及最基本的数组创建,可以有效实现文件的读取。下面介绍另外一种常见的文件读取方式:基于流的。

二、C++文件读写(基于文件流)

基于文件流的方式更加普遍、高效与清晰。需要使用到的是iostream和fstream库。直接给出一个读取位姿的案例。这个案例的数据存储在estimated.txt文件中,每一行7个数据,分别是时间、xyz位置、以四元数格式记载的姿态。这种具有统一表格格式的的数据特别适合使用流数据来读取:

typedef vector<Sophus::SE3d, Eigen::aligned_allocator<Sophus::SE3d>> TrajectoryType;
TrajectoryType ReadTrajectory(const string &path) {ifstream fin(path);TrajectoryType trajectory;if (!fin) {cerr << "trajectory " << path << " not found." << endl;return trajectory;}while (!fin.eof()) {double time, tx, ty, tz, qx, qy, qz, qw;fin >> time >> tx >> ty >> tz >> qx >> qy >> qz >> qw;Sophus::SE3d p1(Eigen::Quaterniond(qx, qy, qz, qw), Eigen::Vector3d(tx, ty, tz));trajectory.push_back(p1);}return trajectory;
}

在读取流的过程中,行是fin指针中段循环的单位。如果要转换数据格式到Eigen等库时,每个小循环中就可以进行类型转换。

总结

本文总结了2种C++语言下的文件读取方式。可以看出,当文件较为简单时,采用统一的文件流形式可以简化代码,而文件较为复杂时,特别是数据结构各异时,编写fscanf函数组合的方式,具有更好的通用性。本文会持续更新,加入更多优秀的文件读写代码。

http://www.jmfq.cn/news/4939543.html

相关文章:

  • 广州微信网站开发公司/网站关键词排名服务
  • 简述网站设计要遵循哪些原则/太原网站推广排名
  • 网站搬家教程/小程序开发公司哪里强
  • 自己怎么做免费网站空间/合肥网
  • 购物网站要多少钱/好看的网页设计作品
  • 网站建设的风格设置/江北seo页面优化公司
  • 用什么做php网站/设计网站排名
  • 域名和网站绑定/seo综合查询是什么意思
  • 做网站时遇到的问题/优帮云排名优化
  • 广州市网站建设科技/网推团队
  • 专做奢侈品的网站/安卓优化大师老版本
  • tk网站域名注册/百度学术论文查重免费
  • 北京营销网站建设/百度seo排名培训 优化
  • 企业安全文化建设评价准则/官网关键词优化价格
  • 石狮制作网站/网站运营
  • 网站制作推广SSL/微博推广
  • 秦皇岛网站建设/小程序搭建
  • 短网址恢复/百度seo排名曝光行者seo
  • wordpress配置文件路径/seo搜索引擎优化方案
  • 合肥哪家做网站好/北京seo招聘网
  • 一个网站百度百科怎么做/seo 推广服务
  • 网站建设论文/青岛百度seo
  • 万维网域名注册查询/公众号排名优化
  • 响应试网站和移动端/推广链接
  • 网站制作 江西/品牌营销策划方案案例
  • 佛山网站设计网站公司/关键词快速上首页排名
  • 地产项目网站/网络设计
  • 做网站赚钱但又不想开公司/免费代理浏览网页
  • 张家港做网站排名/网站托管
  • 做外贸仿牌都用哪些网站/微信指数官网