C++ C++;从字符串对CSV文件中的数据进行排序的代码

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

我编写了一个函数,它解析文件中的数据,并保存在名为content的字符串变量中。 例如:

 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中的每个记录都由两条新行分隔。