C++模仿Numpy常用文本文件读取、写入

经常用C++读入、写出(打印)矩阵数组,觉得要想办法自动解决一下这个问题。于是开始模仿Python的Numpy,矩阵暂时用vector<vector<double>>代替:

*目前是V0.1

实现功能主要如下:

  • ReadTxt.h / ReadTxt.cpp
    • genFromtxt(支持分隔符和注释,制表符视为空格,返回vector<vector<double>>
  • WriteTxt.h / Writetxt.cpp
    • print(显示在屏幕上,fixed,可控制位数)
    • saveTxt(将vector<vector<double>>保存为文件,fixed,可控制位数)

更详细一点的说明见头文件函数定义注释

😄ReadTxt.h

/*
@author: Kan Haoyu
@date: 2021/3/8
@function: Basic text Input 
*/


#pragma once
#ifndef READTXT_H
#define READTXT_H

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <algorithm>

using namespace std;

// read a txt into a vector<vector<double>> ;
// line splited by split_char; 
// string after comment_char will be discarded; 
// line without contents(pure comment) will also be discarded
vector<vector<double>> genFromtxt(const string& file_path, const char split_char, const char comment_char);

// return a string where substring after comment_char will be discarded
string decommentString(const string& str, const char comment_char);

// split string with split_char into a vector<string>
vector<string> splitString(const string& str, const char split_char);

// convert vector<string> into vector<double>
vector<double> asDouble(const vector<string>& vec_str);

// replace all tab('\t') with blankspace(' ') in a string and return the result
string replaceTabWithBlankspace(const string& str);




#endif

😄ReadTxt.cpp

#include "ReadTxt.h"

vector<vector<double>> genFromtxt(const string& file_path, const char split_char, const char comment_char)
{
	ifstream infile;
	string line;
	vector<vector<double>> res;
	string line_replace_tab;
	string line_decomment;

	infile.open(file_path);

	if (!infile) {
		cerr << "Error! genFromtxt file_path is wrong" << endl;
		exit(0);
	}

	while (true) {
		if (infile.eof()) {
			break;
		}
		getline(infile, line);

		// 将'\t'替换为' '防止之后转换出错
		line_replace_tab = replaceTabWithBlankspace(line);
		
		// comment_char 
		// 发现comment_char则舍弃其和其之后的字符
		line_decomment = decommentString(line_replace_tab, comment_char);

		// split_char
		// 按split_char切分进入vector
		// 每一line对应一个vector
		vector<double> vec_i;
		vector<string> vec_str_i;
		vec_str_i = splitString(line_decomment, split_char);
		vec_i = asDouble(vec_str_i);

		// 不留空行
		if (vec_i.size() == 0) {
			continue;
		}

		res.push_back(vec_i);
	}
	return res;
}

string decommentString(const string& str, const char comment_char)
{
	string res;
	size_t found = str.find(comment_char);
	if (found != string::npos) {
		res = str.substr(0, found);
	}
	else {
		res = str;
	}
	return res;
}

vector<string> splitString(const string & str, const char split_char)
{
	vector<string> res;
	stringstream spliter(str);
	string buffer;
	while (getline(spliter, buffer, split_char)) {
		if (buffer.empty()) {
			continue;
		}
		res.push_back(buffer);
	}
	return res;
}

vector<double> asDouble(const vector<string>& vec_str)
{
	vector<double> res;
	res.reserve(vec_str.size());//预留分配,加速作用
	for (int i = 0; i < vec_str.size(); i++) {
		double t = stod(vec_str.at(i));
		res.push_back(t);
	}
	return res;
}

string replaceTabWithBlankspace(const string & str)
{
	string res;
	res = str;
	replace(res.begin(), res.end(), '\t', ' ');
	return res;
}

😄WriteTxt.h

/*
@author: Kan Haoyu
@date: 2021/3/8
@function: Basic vector output to text
*/
#pragma once
#ifndef WRITETXT_H
#define WRITETXT_H

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <iomanip>

using namespace std;

// print a vector<vector<double>> on screen with designated precision, default = 4
void print(const vector<vector<double>>& vec_vec, const int precision = 4);

// save a vector<vector<double>> as ascii in file_path with designated precision, default = 4
void saveTxt(const string& file_path, const vector<vector<double>>& vec_vec, const int precision = 4);


#endif

😄 WriteTxt.cpp

#include "WriteTxt.h"

void print(const vector<vector<double>>& vec_vec, const int precision)
{
	cout << fixed << setprecision(precision);
	for (int i = 0; i < vec_vec.size(); i++) {
		for (int j = 0; j < vec_vec[i].size(); j++) {
			cout << (vec_vec.at(i)).at(j) << " | ";
		}
		cout << "\n";
	}
}

void saveTxt(const string & file_path, const vector<vector<double>>& vec_vec, const int precision)
{
	ofstream outfile;
	outfile.open(file_path);
	
	if (!outfile) {
		cerr << "Error! saveTxt fail open file_path" << endl;
		exit(0);
	}

	outfile << fixed << setprecision(precision);
	for (int i = 0; i < vec_vec.size(); i++) {
		for (int j = 0; j < vec_vec[i].size(); j++) {
			outfile << (vec_vec.at(i)).at(j) << " ";
		}
		outfile << "\n";
	}
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值