C++实现Txt文件存储数组
- 说明
- 大致格式
- 数据读写机制
- 程序
- 最后
说明
首先本人写的Txt存储数组的程序是有一定的格式的,且一个Txt文件只能存储一个数组,如果不满足需求可以直接跳过程序的测试。另外程序不提供数组中单个数值或者字符串的修改,因为修改的效率太低,完全没必要提供,如果这也不满足,可直接跳过程序测试
大致格式
第一行 数组的行数 数组的列数
第二行 a[0][0] a[0][1] … a[0][n]
.
.
.
第n行 a[m][0] a[m][1] … a[m][n]
数据读写机制
数据读取会根据第一行的行列数读取并生成预设类型的数组返回
数据写入会根据写入数组的大小写入第一行,并将数组对应格式的参数写入到对应的位置
程序
//CTxt.h
#pragma once
//用于格式化输入输出txt文件
//使用C++的ifstream和ofstream
#include <string>
#include <cstring>
#include <iostream>
#include <fstream>
#include <vector>
#include "CDebug.h"
#include "CSprintf.h"
#include "Cmyfile.h"
//txt文件格式标准化,表格的格式
//第一行 行数 列数
//第二行~第n行为数据 数据之间采用空格分隔,单空格或多空格均可,行与行采用\r\n分割
using namespace std;
//用于增强ifstream数据的兼容性
class CTxt:public Cmyfile
{
public:
public:CTxt();
CTxt(CString name);
CTxt(string namey);
CTxt(char* name);
//按文件大小或者预定大小读取,如采用int类型读取数据则为:readT<int>()
//不可读空格和\r\n
template<class T>
vector<vector<T>> readT(string name=this->name);
template<class T>
vector<vector<T>> readT(string name,int w,int h);
template<class T>
vector<vector<T>> readT(CString name);
template<class T>
vector<vector<T>> readT(CString name,int w,int h);
//逐行读取
//可读取空格
//读取所有行的数据
vector<CString> readline();
vector<CString> readline(string name);
vector<CString> readline(CString name);
//读取一行数据
CString readOneLine(int line);
CString readOneLine(string name,int line);
CString readOneLine(CString name,int line);
//按文件大小或者预定大小读取,如采用int类型读取数据则为:writeT<int>(vector<vector<int>>vec)
//不要写入空格和\r\n,否则会影响后期的数据读取
template<class T>
bool writeT(vector<vector<T>> vec);
template<class T>
bool writeT(string name, vector<vector<T>> vec);
template<class T>
bool writeT(CString name, vector<vector<T>> vec);
private:
string name;
};
//模板型的函数无法放入到cpp文件中,放入cpp会导致除CTxt.cpp以外的文件无法调用
template<class T>
inline vector<vector<T>> CTxt::readT(string name)
{
ifstream myfile(name.c_str());
if (!myfile.is_open())
{
OutputDebugString(_T("can not open this file"));
return { };
}
int w, h;
myfile >> w >> h;
vector<vector<T>> vec;
vec.resize(w);
for (int i = 0; i < w; i++)
{
vec[i].resize(h);
}
for (int i = 0; i < w; i++)
{
for (int j = 0; j < h; j++)
{
myfile >> vec[i][j];
}
}
return vec;
}
template<class T>
inline vector<vector<T>> CTxt::readT(string name, int w, int h)
{
ifstream myfile(name.c_str());
if (!myfile.is_open())
{
OutputDebugString(_T("can not open this file"));
return { };
}
int w1, h1;
myfile >> w1 >> h1;
if (w > w1 || h > h1)
reutrn{ };
vector<vector<T>> vec;
vec.resize(w);
for (int i = 0; i < w; i++)
{
vec[i].resize(h);
}
for (int i = 0; i < w; i++)
{
for (int j = 0; j < h; j++)
{
myfile >> vec[i][j];
}
}
return vec;
}
template<class T>
inline vector<vector<T>> CTxt::readT(CString name)
{
string name1 = CT2A(name.GetBuffer());
return readT<T>(name1);
}
template<class T>
inline vector<vector<T>> CTxt::readT(CString name, int w, int h)
{
string name1 = CT2A(name.GetBuffer());
return readT<T>(name1, w, h);
}
template<class T>
inline bool CTxt::writeT(vector<vector<T>> vec)
{
return writeT<T>(name, vec);
}
template<class T>
inline bool CTxt::writeT(string name, vector<vector<T>> vec)
{
if (vec.empty()) //空的,不做任何处理
return false;
if (name.empty())
return false;
unsigned int w = vec.size();
unsigned int h = vec[0].size();
ofstream outfile(name.c_str());
if (!outfile.is_open())
return false;
outfile.clear();
outfile << w << " " << h << "\n";
for (unsigned int i = 0; i < w; i++)
{
for (unsigned int j = 0; j < h; j++)
{
outfile << vec[i][j];
if (j!= h - 1)
outfile << " ";
}
outfile <<"\n";
}
outfile.close();
return true;
}
template<class T>
inline bool CTxt::writeT(CString name, vector<vector<T>> vec)
{
string name1 = CT2A(name.GetBuffer());
return writeT(name1, vec);
}
//CTxt.cpp
#include "pch.h"
#include "CTxt.h"
CTxt::CTxt()
{
this->name = "data.txt";
}
CTxt::CTxt(CString name)
{
this->name =(CStringA) name;
}
CTxt::CTxt(string name)
{
this->name = name;
}
CTxt::CTxt(char * name)
{
this->name = name;
}
vector<CString> CTxt::readline()
{
ifstream infile;
infile.open(name.c_str(), ios::in);
if (!infile.is_open())
{
CDebug() << "读取文件失败"<<Cendl;
return{ };
}
int w, h;
infile >> w >> h;
//第三种读取方法
string buf;
vector<CString> vec;
while (getline(infile, buf))
{
vec.push_back(CString(buf.c_str()));
CDebug() << buf <<Cendl;
}
return vec;
}
vector<CString> CTxt::readline(string name)
{
ifstream infile;
infile.open(name.c_str(), ios::in);
if (!infile.is_open())
{
CDebug() << "读取文件失败" << Cendl;
return { };
}
int w, h;
infile >> w >> h;
//第三种读取方法
string buf;
getline(infile, buf); //第0行数据跳过,这一行为行数和列数的参数
vector<CString> vec;
while (getline(infile, buf))
{
vec.push_back(CString(buf.c_str()));
CDebug() <<buf << Cendl;
}
return vec;
}
vector<CString> CTxt::readline(CString name)
{
return readline(name.GetBuffer());
}
CString CTxt::readOneLine(int line)
{
ifstream infile;
infile.open(name.c_str(), ios::in);
if (!infile.is_open())
{
CDebug() << "读取文件失败" << Cendl;
return { };
}
int w, h;
infile >> w >> h;
//第三种读取方法
string buf;
getline(infile, buf); //第0行数据跳过,这一行为行数和列数的参数
int i = 0;
while (getline(infile, buf))
{
if (i >= line)
return CString(buf.c_str());
i++;
}
return { }; //超出范围不输出
}
CString CTxt::readOneLine(string name,int line)
{
ifstream infile;
infile.open(name.c_str(), ios::in);
if (!infile.is_open())
{
CDebug() << "读取文件失败" << Cendl;
return { };
}
int w, h;
infile >> w >> h;
//第三种读取方法
string buf;
getline(infile, buf); //第0行数据跳过,这一行为行数和列数的参数
for (int i = 0; i < line; i++)
{
getline(infile, buf);
}
return CString(buf.c_str());
}
CString CTxt::readOneLine(CString name,int line)
{
return readOneLine(name.GetBuffer(), line);
}
最后
目前可以有效的数组的读写操作,但是半模板的操作实在是给后续的操作提供了极大的不变,之后会出第二版纯模板类程序。