天天看点

读txt实验数据写入Excel(c++)

作为一名电化学专业大四狗,天天实验,处理实验数据真的是烦人,尤其是需要打开多个文本文件,选好要用的数据,复制,粘贴,分列,重复......
所以写了个东西,让它自己搞去吧哈哈哈哈......
针对的是有规律的txt数据文件,把文件拖到设定好的文件夹里,运行一两秒就好了......
生成的是csv文件可以直接用Excel或者wps打开,然后直接作图神魔的就行了......
           
#include<iostream>
#include<fstream>
#include<string>
#include<vector>
#include<io.h>
#include<cstring>
#include<windows.h>
#include<queue>

using namespace std;

string IN_FILE_PATH;//txt文件存放位置

const string OUT_FILE_PATH="OUT_FILE.csv";//写入的文件

vector<string> file_list;//txt文件列表

ifstream IF[50];//输入文件指针表

ofstream OF;//写出文件指针

unsigned int file_cnt;//txt文件个数

unsigned int open_file_cnt;//打开的txt文件个数

string line;//暂存读入的一行

vector<string> split_elem;//存储一行分割后的数据

bool flag=false;//此行是否有输出

queue<string> order;

//获得程序当前路径,为搜索待处理文件做准备
void get_running_path()
{
	char path_name[512];
	string path;
	string::size_type pos;
	
	GetModuleFileName(NULL,path_name,sizeof(path_name));//获取路径加名字
	
	path.assign(path_name);
	pos=path.find_last_of('\\',path.npos);
	
	IN_FILE_PATH=path.substr(0,pos+1).append("IN_FILE\\");//得到txt文件存放的文件夹
}

//搜索所有待处理txt文件
void get_file_list(string main_path)
{
	intptr_t handle;//句柄
	_finddata_t file_info;//文件信息
	string search_path;//搜索路径
	string ans_path;//结果路径
	
	if((handle=_findfirst(search_path.assign(main_path).append("*.*txt").c_str(),&file_info))!=-1)
	{
		do
		{
			if(strcmp(file_info.name,".")&&strcmp(file_info.name,".."))//有效文件
			{
				file_list.push_back(ans_path.assign(main_path).append(file_info.name));
			}
		}
		while(!_findnext(handle,&file_info));
	}
	
	file_cnt=file_list.size();//获得文件个数
	
	_findclose(handle);//关闭句柄
}

//打开输入输出文件
void open_all_files()
{
	for(int i=0;i<file_cnt;++i)//打开输入文件
	{
		IF[i].open(file_list[i].c_str());
	}
	
	open_file_cnt=file_cnt;//打开文件个数
	
	OF.open(OUT_FILE_PATH.c_str(),ios::out | ios::trunc);//打开输出文件
}

//单行数据分割
void string_split(string delim)
{
	string::size_type pos_1,pos_2=0;
	while(pos_2!=line.npos){
		pos_1=line.find_first_not_of(delim,pos_2);
		if(pos_1==line.npos) break;
		pos_2=line.find_first_of(delim,pos_1);
		split_elem.push_back(line.substr(pos_1,pos_2-pos_1));
	}
}

//文件读完时的写入方式
void cope_over(int i)
{
	if(i==file_cnt-1)//最后一列输出endl
	{
		for(int j=0;j<split_elem.size()-1;++j)
		{
			OF<<",";
		}
		OF<<endl;
	}
	else
	{
		for(int j=0;j<split_elem.size();++j)
		{
			OF<<",";
		}
	}
}

//文件未读完时的写入方式
void cope_not_over(int i)
{
	if(i!=file_cnt-1)
	{
		for(int j=0;j<split_elem.size();++j)
		{
			OF<<split_elem[j]<<",";
		}
	}
	else//最后一行输出endl
	{
		for(int j=0;j<split_elem.size()-1;++j)
		{
			OF<<split_elem[j]<<",";
		}
		OF<<split_elem[split_elem.size()-1]<<endl;
	}
}

//判断数据是否合法,此处可以进行调整以适应不同需要
bool legal()
{
	if(line=="") return false;
	else
	{
		for(auto c:line)
		{
			if(c>='A'&&c<='Z') return false;
		}
	}
	return true;
}

//在第一列写出文件的排列顺序
void add_order()
{
	if(!order.empty())
	{
		OF<<order.front()<<",";
		order.pop();
	}
	else
	{
		OF<<",";
	}
}

//读入主程序
void read_files()
{
	while(open_file_cnt)//有文件打开则持续读入
	{
		flag=false;//当前行还未有数据
		
		for(int i=0;i<file_cnt;++i)//循环读每个文件
		{
			if(!IF[i])//文件已关闭
			{
				cope_over(i);
			}
			else//文件未关闭
			{
				if(!getline(IF[i],line))//文件读完
				{
					IF[i].close();//关闭文件
					open_file_cnt--;//更新打开文件数
					cope_over(i);
					continue;
				}
				
				if(!legal())//数据非法
				{
                    i--;//继续读此文件,以保证顶部对对齐
                    continue;
				}
				
				if(!flag) add_order();//此行还没数据时,看是否需要写出文件顺序
				
				flag=true;//此行有数据了
			    
			    split_elem.clear();//清空split_elem
			    string_split(" ,");//分割line得到split_elem
				    
				cope_not_over(i);
			}
		}
	}
	
	OF.close();//关闭输出文件
}

//得到文件的顺序队列
create_order()
{
	order.push("文件顺序");
	for(int j=0;j<file_list.size();++j)
	{
		string s=file_list[j];
		string::size_type pos=s.find_last_of("\\",s.npos);
		order.push(s.substr(pos+1,s.npos));
	}
}

int main()
{
	get_running_path();
	
	get_file_list(IN_FILE_PATH);//获得所有txt文件
	
	create_order();
	
	open_all_files();//打开所有文件
	
	read_files();//读取
	
	system("start out_file.csv");
	
	return 0;
}
           
读txt实验数据写入Excel(c++)
读txt实验数据写入Excel(c++)
读txt实验数据写入Excel(c++)