c++ 解析.csv文件(全)

c++ 解析.csv文件(全),第1张

c++ 解析csv文件 

一、项目要求:

(1) 这个程序需要做到将csv文件的内容读取进来解析,并将每一个联系人的数据进行打印;
(2) 用户输入排序的属性key,将排序完成的结果打印出来;
(3) 能够对错误格式的文件进行检测;
(4) 能够对错误的数据进行容错;
(5) 文件编码格式不限,输出为UTF8格式


二、分析问题

1.问题1对与csv文件的读取,要如何读取,想到可以对文件进行读 *** 作的文件方法函数,对文件读取之后怎么去进行将每一行的数据进行剪切成每一个主题。


剪切后的数据如何保持,是用二维数组,还是用结构体(分析得出为了后面的任务方便进行,还是用结构体来存储数据是最好的)

2.问题二 属性key的排序,对于排序,比如 用id ,age 等数字型的数据项进行排序,其中的排序是如何实现?是升序还是降序?这个都要了解。


排序好了之后怎么再次打印出来,个用户查看等

3.要考虑到csv文件的错误格式有哪些,什么场景下会比较容易产生错误的格式文件,又如何对其进行检测,检测完之后如何让用户更改过来等。


4.问题四 对错误的数据进行容错,首先要知道了解,数据的错误又那些?其中我下面的代码实现中实现两个常见的错误数据例如 用分号注释的字符 "****",或 ","这些,csv文件有编码格式可能不符合,导致解析到数据乱码


三、代码实现

#include 
#include 
#include 
#include 
#include 
#include

#include 
using namespace std;

struct student {          //成员结构体

	int id;
	string name;
	int age;
	string hobby;


};
class new_csv {                    //创建一个功能类

public:

	void output(vector& vectorclient);  //排序输出函数

	int examine(int* num, int& bit);
	char* Fault(string sum);


};

std::wstring utf8ToUtf16(const std::string& utf8String)
{
	std::wstring sResult;
	int nUTF8Len = MultiByteToWideChar(CP_UTF8, 0, utf8String.c_str(), -1, NULL, NULL);
	wchar_t* pUTF8 = new wchar_t[nUTF8Len + 1];

	ZeroMemory(pUTF8, nUTF8Len + 1);
	MultiByteToWideChar(CP_UTF8, 0, utf8String.c_str(), -1, pUTF8, nUTF8Len);
	sResult = pUTF8;
	delete[] pUTF8;

	return sResult;
}
LPCWSTR stringToLPCWSTR(std::string orig)
{
	size_t origsize = orig.length() + 1;
	const size_t newsize = 100;
	size_t convertedChars = 0;
	wchar_t* wcstring = (wchar_t*)malloc(sizeof(wchar_t) * (orig.length() - 1));
	mbstowcs_s(&convertedChars, wcstring, origsize, orig.c_str(), _TRUNCATE);
	return wcstring;
}

std::string wstring2string(wstring wstr)
{
	string result;
	//获取缓冲区大小,并申请空间,缓冲区大小事按字节计算的  
	int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL);
	char* buffer = new char[len + 1];
	//宽字节编码转换成多字节编码  
	WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), buffer, len, NULL, NULL);
	buffer[len] = '\0';
	//删除缓冲区并返回值  
	result.append(buffer);
	delete[] buffer;
	return result;
}
char* UnicodeToUTF8(wchar_t* wszcString)
{
	int utf8Len = ::WideCharToMultiByte(CP_UTF8, NULL, wszcString, int(wcslen(wszcString)), NULL, 0, NULL, NULL);
	char* szUTF8 = new char[utf8Len + 1];    //给'\0'分配空间
	::WideCharToMultiByte(CP_UTF8, NULL, wszcString, int(wcslen(wszcString)), szUTF8, utf8Len, NULL, NULL);    //转换
	szUTF8[utf8Len] = '\0';

	return szUTF8;
}
std::string utf8ToUnicode(const char* route) {
	//return route;
	wstring wfilepath = utf8ToUtf16(route);
	return wstring2string(wfilepath);
}
std::string TCHAR2STRING(TCHAR* STR)
{
	int iLen = ::WideCharToMultiByte(CP_ACP, 0, STR, -1, NULL, 0, NULL, NULL);
	char* chRtn = new char[iLen * sizeof(char)];
	::WideCharToMultiByte(CP_ACP, 0, STR, -1, chRtn, iLen, NULL, NULL);
	std::string str(chRtn);
	return str;
}


//id的排序函数
bool sortid(const student& a, const student& b)
{
	if (a.id < b.id)
	{
		return true;

	}
	else {
		return false;
	}

}

//age排序函数

bool sortage(const student& a, const student& b)
{
	if (a.age < b.age)
	{
		return true;

	}
	else {
		return false;
	}

}

void  new_csv::output(vector& vectorclient)   //排序输出函数
{

	for (vector::iterator it = vectorclient.begin(); it != vectorclient.end(); it++)
	{
		::cout << "id: " << it->id << " name: " << it->name << " age: " << it->age << " hobby: " << it->hobby << endl;
	}

}
int new_csv::examine(int* num, int& bit)   //对输入文件格式进行判断是否有误
{
	for (int i = 1; i < bit - 1; i++)
	{
		if (num[i] == num[i + 1])
		{
			cout << "csv文件对应要求无误" << endl;
			return 0;

		}
		else
			cout << "请检查文件中是否有空格,或文件编写格式有问题,导致文件信息对应不上" << endl;
		return 0;
	}


}

char* new_csv::Fault(string linestr)
{
	char* sum;
	sum = (char*)malloc(100);
	int len_str = strlen(linestr.c_str());
	int k = 0;
	memset(sum, 0, 100);
	for (int j = 0; j < len_str; j++)
	{
		/*if (linestr[j] == '*')
		{
			linestr[j] = ',';
		}*/
		if (linestr[j] == '"' && linestr[j + 1] == '"')                  //对fgets到的数组结尾的换行符进行替换
		{
			sum[k] = linestr[j];
			k++;
			j = j + 1;
		}
		else if (linestr[j] == '"' && linestr[j + 1] != '"') {
		
				sum[k] = linestr[j + 1];
				k++;
				j = j + 1;
			
		}
		else {
			if (linestr[j] == ',' && linestr[j + 1] == '"' && linestr[j-1] =='"')
			{
				sum[k] = '*';
				k++;
			}
			else
			{
				sum[k] = linestr[j];
				
				k++;
			}
		}
	}
	return sum;

}
int main()
{

	ifstream infile("newfile.csv", ios::in);//infile来自fstream,ifstream为输入文件流(从文件读入)

	string linestr;
	int size_1[10] = { 0 };
	char* sum;
	char* Second_sum;
	int n1 = 1;
	new_csv pot;
	vector vectorclient;
	int num = 0;
	string key;
	int k = 0;
	while (getline(infile, linestr)) 		//读入整行数据到linestr里
	{

		n1 = 1;                              //定义对一行中的 逗号分割的每一段进行计数用来判断存储的区域
		sum = pot.Fault(linestr);
		stringstream ss(sum);//来自sstream
		string str;

		if (num > 0)
		{	//实现只对数据写入vector ,不对标题写入,从而进行排序 
			//按照逗号分隔

			student client;

			while (getline(ss, str, ','))    //数据进行循环存储
			{
				
				int len = strlen(str.c_str());
				for (int j = 0; j < len;j++)
				{
					if (str[j] == '*')
					{
						str[j] = ',';
					}
				}
				
				//cout<> key;

	if (key == "id")
	{
		sort(vectorclient.begin(), vectorclient.end(), sortid);
		::cout << "————id排序后的信息如下————" << endl;
		pot.output(vectorclient);

	}
	else if (key == "age")
	{

		sort(vectorclient.begin(), vectorclient.end(), sortage);
		::cout << "————age排序后的信息如下————" << endl;
		pot.output(vectorclient);
	}
	else {

		cout << "无输入选项,无法排序,原信息如下" << endl;
		pot.output(vectorclient);
	}

	return 0;
}
运行结果:

 excel(看到文件中乱码,因为设置了不支持utf-8的编码,所以乱码,更改编码可以直接再notepad++中打开更改就行)

vs运行界面(通过代码将utf-8中的编码格式转换为Unicode可以正常输出中文) 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/562509.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-04-01
下一篇 2022-04-01

发表评论

登录后才能评论

评论列表(0条)

保存