Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <fstream>
- #include <string>
- #include <iostream>
- namespace {
- void replace_col(const char* inpath, const char* outpath, const char* label,
- const char* replacement)
- {
- std::ifstream infile(inpath);
- if(! infile.good())
- throw std::ios::failure("Cannot open input");
- infile.exceptions(std::ios::badbit);
- std::ofstream outfile(outpath);
- if(! outfile.good())
- throw std::ios::failure("Cannot create output");
- outfile.exceptions(std::ios::badbit | std::ios::failbit);
- std::string buf;
- if(! std::getline(infile, buf))
- return; // empty file
- // Handle header. Look for column index
- int replacecol = 0;
- bool found;
- // we stop when we haven't found a separator in the last iteration
- for(std::size_t offset = 0, cursep = 0; cursep != std::string::npos;
- ++replacecol, offset = cursep + 1) {
- cursep = buf.find(',', offset);
- if((found = ! buf.compare(offset, cursep - offset, label)))
- break;
- }
- if(! found)
- throw std::ios::failure("Column not found");
- outfile << buf << '\n'; // save header unchanged
- while(std::getline(infile, buf)) {
- std::size_t offset, cursep;
- int curcol;
- for(offset = 0, cursep = 0, curcol = 0; cursep != std::string::npos;
- ++curcol, offset = cursep + 1) {
- cursep = buf.find(',', offset);
- if(offset) // add separator to previous column
- outfile << ',';
- /*
- * one loop before the replacement and one after it would be more
- * efficient but let's keep it simple
- */
- if(curcol == replacecol)
- outfile << replacement;
- else
- outfile << buf.substr(offset, cursep - offset);
- }
- outfile << '\n';
- }
- // don't rely on dtor so that we can catch IO errors
- outfile.close();
- }
- }
- int main(int argc, char** argv)
- {
- if(argc != 5) {
- std::cerr << "Usage: " << argv[0]
- << " INPUT.csv COLUMN REPLACEMENT OUTPUT.csv\n";
- return 1;
- }
- replace_col(argv[1], argv[4], argv[2], argv[3]);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement