C++ C++;从字符串对CSV文件中的数据进行排序的代码
我编写了一个函数,它解析文件中的数据,并保存在名为content的字符串变量中。 例如:C++ C++;从字符串对CSV文件中的数据进行排序的代码,c++,csv,sorting,dynamic,C++,Csv,Sorting,Dynamic,我编写了一个函数,它解析文件中的数据,并保存在名为content的字符串变量中。 例如: String Content = "ABC Corp : Processed server: dfgh123 passed = 1250; remaining = 0; DTY Corp : Processed serv
String Content = "ABC Corp : Processed
server: dfgh123
passed = 1250;
remaining = 0;
DTY Corp : Processed
server: dty123
passed = 120;
remaining = 1;
QRS Corp : Processed
server: qrs123
passed = 250;
remaining = 0;"
上面的值是从一个巨大的文本文件中解析出来的,保存在一个字符串中。
现在,我想编写一个函数,将上述字符串按以下格式排序为csv文件:
Processed Server Passed remaining //column name
ABC corp dfgh123 1250 0
DTY Corp dty123 120 1
QRS corp qrs123 250 0
这是我的解析代码
#include <fstream>
#include <sstream>
#include <iostream>
#include <string>
#include <windows.h>
#include <atlbase.h>
#include <atlstr.h>
#include <functional>
#include <string>
#include <algorithm>
#include <stdio.h>
#include "time.h"
#include <ctime>
#include <iomanip>
#include <vector>
#include <numeric>
#include <iterator>
#include <locale>
#include <codecvt>
#include <map>
#include <utility>
#include <cctype>
#pragma warning(disable: 4996)
using namespace std;
void findAndReplaceAll(std::string& data, std::string toSearch, std::string replaceStr)
{
// Get the first occurrence
size_t pos = data.find(toSearch);
// Repeat till end is reached
while (pos != std::string::npos)
{
// Replace this occurrence of Sub String
data.replace(pos, toSearch.size(), replaceStr);
// Get the next occurrence from the current position
pos = data.find(toSearch, pos + replaceStr.size());
}
}
int main(int argc, char** argv)
{
string filecontent;
wchar_t Path[256] = { 0 };
wchar_t ExePath[256] = { 0 };
wchar_t ConfigPath[512] = { 0 };
GetModuleFileNameW(NULL, Path, sizeof(Path));
wcscpy(ExePath, Path);
PathRemoveFileSpecW(Path); // D:\vstudio\ConsoleApplication3\Debug
std::ofstream myfile;
wstring ws1(Path);
string szfilename(ws1.begin(), ws1.end());
USES_CONVERSION;
WIN32_FIND_DATA file;
string pathtoDataFolder = szfilename + "\\Export_*.txt";
HANDLE search_handlexml = FindFirstFile(A2W(pathtoDataFolder.c_str()), &file);
string Path1("");
string Path2("");
if (search_handlexml)
{
do
{
USES_CONVERSION;
PTSTR pszFileName = file.cFileName;
//string skippedfilename = T2A(pszFileName);
TCHAR szBuf[1024], szBuf1[1024];
//szFileName = szFileName + T2A(pszFileName);
Path1 = szfilename + "\\" + T2A(pszFileName); //D:\vstudio\ConsoleApplication3\DebugExport_20190617090328.txt
Path2 = szfilename + "\\textfile.csv";
if ((Path1.find(".exe") != string::npos) || (Path1.find(".csv") != string::npos)|| (Path1.find(".ini") != string::npos))
{
//Log.WriteLog("Invalid file %s", skippedfilename.c_str());
bool bret = false;
}
string abc = Path1.c_str(); //D:\vstudio\ConsoleApplication3\Release\Export_20190617090328.txt
std::stringstream ss;
std::ifstream fin(abc);
ss << fin.rdbuf(); // dump file contents into a stringstream
std::string const& s = ss.str();
if (s.size() % sizeof(wchar_t) != 0)
{
std::cerr << "file not the right size\n"; // must be even, two bytes per code unit
return 1;
}
std::wstring ws;
ws.resize(s.size() / sizeof(wchar_t));
std::memcpy(&ws[0], s.c_str(), s.size()); // copy data into wstring
//std::wstring wide(L"Wide");
std::string content(ws.begin(), ws.end());
size_t pos = content.find("Summary:");
content.erase(0, pos + 8);
std::string the_prefix_you_want = content.substr(0, content.find("Remaining = "));
the_prefix_you_want.erase(std::remove(the_prefix_you_want.begin(), the_prefix_you_want.end(), '\n'), the_prefix_you_want.end());
findAndReplaceAll(the_prefix_you_want, ";", " \n");
findAndReplaceAll(the_prefix_you_want, ":", " : ");
findAndReplaceAll(the_prefix_you_want, "=", " = ");
filecontent = filecontent + Path1.c_str() + the_prefix_you_want;
} while (FindNextFile(search_handlexml, &file));
myfile.open(Path2);
myfile << filecontent;
myfile.close();
}
return 0;
//PathRemoveFileSpecA((LPSTR)Path.c_str());
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括“time.h”
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#杂注警告(禁用:4996)
使用名称空间std;
void findAndReplaceAll(std::string&data,std::string to search,std::string replaceStr)
{
//第一次出现
size\u t pos=数据查找(toSearch);
//重复,直到到达终点
while(pos!=std::string::npos)
{
//替换此子字符串
data.replace(pos,toSearch.size(),replaceStr);
//从当前位置获取下一个引用
pos=data.find(toSearch,pos+replaceStr.size());
}
}
int main(int argc,字符**argv)
{
字符串文件内容;
wchar_t Path[256]={0};
wchar_t ExePath[256]={0};
wchar_t ConfigPath[512]={0};
getModuleFileName(NULL,Path,sizeof(Path));
wcscpy(ExePath,Path);
PathRemoveFileSpecW(Path);/D:\vstudio\ConsoleApplication3\Debug
std::流myfile;
wstring ws1(路径);
字符串文件名(ws1.begin(),ws1.end());
使用_转换;
WIN32_FIND_数据文件;
字符串pathtoDataFolder=szfilename+“\\Export.*.txt”;
HANDLE search\u handlexml=FindFirstFile(A2W(pathtoDataFolder.c_str()),&file);
字符串路径1(“”);
字符串路径2(“”);
if(search_handlexml)
{
做
{
使用_转换;
PTSTR pszFileName=file.cFileName;
//字符串skippedfilename=T2A(pszFileName);
TCHAR szBuf[1024],szBuf1[1024];
//szFileName=szFileName+T2A(pszFileName);
路径1=szfilename+“\\”+T2A(pszFileName);/D:\vstudio\ConsoleApplication3\DebugExport\u 20190617090328.txt
路径2=szfilename+“\\textfile.csv”;
if((Path1.find(“.exe”)!=string::npos)| |(Path1.find(“.csv”)!=string::npos)| |(Path1.find(.ini”)!=string::npos))
{
//Log.WriteLog(“无效文件%s”,跳过文件名.c_str());
布尔-布雷特=假;
}
字符串abc=Path1.c_str();//D:\vstudio\ConsoleApplication3\Release\Export_20190617090328.txt
std::stringstream-ss;
标准::ifstream fin(abc);
ss我建议不要将解析结果存储在单个字符串中,而是将结果存储在结构向量中。
这应该很好,因为您的所有内容都具有相同的结构
我给出了一个示例,说明了如何使用它将数据存储在向量中,并在do while循环完成解析后输出
我假设循环体生成一行信息。如果不是这样,则需要相应地修改下面的内容
/* All of your includes */
// trim from start (in place)
static inline void ltrim(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(),
std::not1(std::ptr_fun<int, int>(std::isspace))));
}
// trim from end (in place)
static inline void rtrim(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(),
std::not1(std::ptr_fun<int, int>(std::isspace))).base(), s.end());
}
// trim from both ends (in place)
static inline void trim(std::string &s) {
ltrim(s);
rtrim(s);
}
struct Row {
Row() {}
Row(const std::string& content) {
std::istringstream ins(content);
std::string tmp;
getline(ins, tmp);
name = tmp.substr(0, tmp.find(":")-1);
getline(ins, tmp);
server = tmp.substr(tmp.find(":")+1, tmp.length());
trim(server);
ins >> tmp >> tmp >> passed >> tmp >> tmp >> tmp >> remaining;
}
std::string name;
std::string server;
size_t passed;
size_t remaining;
};
void findAndReplaceAll(std::string& data, std::string toSearch, std::string replaceStr) {
// Body elided for brevity
}
int main(int argc, char** argv) {
// Your setup code.
if (search_handlexml) {
vector<Row> rows;
do {
// Your parsing code
// until you assign to filecontent
filecontent = Path1.c_str() + the_prefix_you_want;
size_t pos = filecontent.find("\n\n");
while (pos != std::string::npos) {
rows.push_back(Row(filecontent.substr(0, pos)));
filecontent = filecontent.substr(pos+1, filecontent.length());
}
rows.push_back(Row(filecontent));
} while (FindNextFile(search_handlexml, &file));
// OUTPUT TO CSV FILE (sample code writing to cout in CSV format (comma separated))
std::cout << "Processed,Server,Passed,remaining" << std::endl;
for (size_t i = 0; i < rows.size(); ++i) {
std::cout << "\"" << rows[i].name << "\",";
std::cout << "\"" << rows[i].server << "\",";
std::cout << rows[i].passed << "," << rows[i].remaining << endl;
}
}
return 0;
}
/*您的所有服务都包括*/
//从开始修剪(就地)
静态内联void ltrim(std::string&s){
s、 擦除(s.begin(),std::find_if(s.begin(),s.end(),
std::not1(std::ptr_fun(std::isspace));
}
//从末端修剪(到位)
静态内联void rtrim(标准::字符串&s){
s、 擦除(std::find_if(s.rbegin(),s.rend(),
std::not1(std::ptr_-fun(std::isspace)).base(),s.end();
}
//两端修剪(到位)
静态内嵌空心修剪(标准::字符串和s){
ltrim(s),;
rtrim(s),;
}
结构行{
行(){}
行(常量标准::字符串和内容){
std::istringstream插件(内容);
std::字符串tmp;
getline(ins、tmp);
name=tmp.substr(0,tmp.find(“:”)-1);
getline(ins、tmp);
server=tmp.substr(tmp.find(“:”)+1,tmp.length();
trim(服务器);
ins>>tmp>>tmp>>通过>>tmp>>tmp>>tmp>>剩余;
}
std::字符串名;
字符串服务器;
通过的尺寸;
剩余尺寸;
};
void findAndReplaceAll(std::string&data,std::string to search,std::string replaceStr){
//为简洁起见,删去了正文
}
int main(int argc,字符**argv){
//您的设置代码。
if(search_handlexml){
向量行;
做{
//您的解析代码
//直到您分配给filecontent
filecontent=Path1.c_str()+所需的前缀;
size\u t pos=filecontent.find(“\n\n”);
while(pos!=std::string::npos){
rows.push_back(Row(filecontent.substr(0,pos));
filecontent=filecontent.substr(pos+1,filecontent.length());
}
rows.push_back(Row(filecontent));
}while(FindNextFile(search_handlexml,&file));
//输出到CSV文件(以CSV格式(逗号分隔)写入cout的示例代码)
std::我可以将你的CSV文件解析为包含所有必填字段的结构向量。你可以分享一个片段或例子来帮助我了解更多吗?请发布你的解析代码;我会修改我添加的代码。字符串没有被完全解析。它只带来单行的值。因为在现实中字符串变量“filecontent”有数千条记录。我知道了,因此do While循环的每次迭代都将读取多条记录。在这种情况下,您可以在“`”上重复拆分\n\n“”并在存在更多记录时继续将新行推送到向量上。从您的示例中可以看出,filecontent中的每个记录都由两条新行分隔。