天天看點

讀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++)