经常用C++读入、写出(打印)矩阵数组,觉得要想办法自动解决一下这个问题。于是开始模仿Python的Numpy,矩阵暂时用vector<vector<double>>
代替:
*目前是V0.1
实现功能主要如下:
- ReadTxt.h / ReadTxt.cpp
- genFromtxt(支持分隔符和注释,制表符视为空格,返回
vector<vector<double>>
)
- genFromtxt(支持分隔符和注释,制表符视为空格,返回
- 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";
}
}