0

I have CSV data file contained follow info:

-0.2500000000,15,15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;0;0;0;0;0;15;0;0,0,0

I only want to add double quotes around those data with semi-colon between them. And I know a specific data that needs to add double quotes.

After add double quotes it should be like this.

-0.2500000000,15,"15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;0;0;0;0;0;15;0;0",0,0

I need to add double quotes for each line of CSV data text line, re-write back to samefile or different. What I plan to do is, using boost token

typedef boost::tokenizer <boost::escaped_list_separator<char> > my_tokenizerDL;

while (getline(infile, line) && lineCount <= NumOfRecords)
{
    for (my_tokenizerDL::iterator it(tok.begin()), end(tok.end()); it != end; ++it)
    {
        mystrDL.push_back(*it);
    }

    for (vector < string >::iterator _mit(mystrDL.begin()); _mit != mystrDL.end(); _mit++)
    {
        //get token position and add double quotes 
        //...........
        //...........
    }
}

////////////dump back to file/////////////////

If you have some advises, I appreciate for your opinions.

================================================================================= After Chad helped out, here are the whole codes which are working as what I need: Purpose: Read csv data txt file each line, then search for column which has ";" between them, and add double quotes around them. Finally, write it back to file. There is an extra "," at the end of each csv data line. I did not fix it!

    ifstream infile("c:\\inputD.csv");
if (!infile)
    return EXIT_FAILURE;


ofstream CSVToFile("c:\\TestCSV.csv", ios::out);
std::string line_from_file;
std::vector<std::string> split_line_to_file;
while (getline(infile, line_from_file))
{       
    boost::split(split_line_to_file, line_from_file, boost::is_any_of(","));

    for(auto str = split_line_to_file.begin(), end = split_line_to_file.end();
        str != end; ++str)
    {

        if(std::string::npos != str->find(';'))
            (*str) = "\"" + (*str) + "\",";
        else
            (*str) = (*str) + ",";

        CSVToFile << (*str);
        std::cout<<*str;

        if (*str == split_line_to_file.back())
            break;

    }
    CSVToFile << ";"<<std::endl;
    std::cout<<std::endl;
}
infile.close();
CSVToFile.close();
AndrewS
  • 177
  • 5
  • 21
  • 3
    Writing a C++ program for this computation? This is a job for sed, awk or perl. Using the proper tool this is going to require just a single command not even worth saving in a script file (i.e. you could just use `perl -e ...` instead of writing a .pl file). – 6502 Sep 01 '11 at 14:39
  • Duplicate of the following question: http://stackoverflow.com/questions/1120140/csv-parser-in-c – Zamfir Kerlukson Feb 23 '13 at 10:01

1 Answers1

3

If you format is as simple as you describe, I'd use boost::split given the string and the delimeter of ','. Then just put quotes around any string that contains a ;.

Similar to this:

// warning:  pseudo code...

std::string line_from_file;
std::vector<std::string> split_line_to_file;

boost::split(split_line_to_file, line_from_file, boost::is_any_of(","));

for(auto str = split_line_to_file.begin(), end = split_line_to_file.end();
    str != end; ++str)
{
   if(std::string::npos != str->find(';'))
      (*str) = "\"" + (*str) + "\"";
}
Chad
  • 18,706
  • 4
  • 46
  • 63
  • Thanks Chad. Your way is more generic than I expected. I will try and accept your answer later. Thanks for your times. – AndrewS Sep 01 '11 at 14:46
  • ::split needs 3 arguments, since you had only two, the result arg is missing as refer to your auto str. I guess I have to the iterate – AndrewS Sep 01 '11 at 15:34
  • Edited my answer, `split()` does require 3 arguments, the first being the result container. See above, it should still work for this purpose. – Chad Sep 01 '11 at 15:37
  • Thanks, Chad. Error is gone, but I got this compile error. "D:\boost_tokenizer\boost_1_45_0\boost/algorithm/string/detail/finder.hpp(583): error C2064: term does not evaluate to a function taking 1 arguments" – AndrewS Sep 01 '11 at 16:42
  • Edited again. 3rd argument is a functor, you can use `boost::is_any_of()` for this. See the related question here: http://stackoverflow.com/questions/236129/how-to-split-a-string-in-c – Chad Sep 01 '11 at 16:53
  • Perfectly. Thanks for your free supports and times. Working now. – AndrewS Sep 01 '11 at 16:59
  • Ok. split delim should be ",", not ";". after I do that, it produced follow output "-0.2500000000 15 "15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;15;0;0;0;0;0;15;0;0" 0 0 - "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0"" – AndrewS Sep 01 '11 at 17:13
  • Can you edit your post from ";" to ","? boost::split(split_line_to_file, line_from_file, boost::is_any_of(";")); --------> ",". – AndrewS Sep 01 '11 at 17:25