Guest User

Untitled

a guest
Feb 16th, 2018
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.39 KB | None | 0 0
  1. #include <algorithm>
  2. #include <experimental/filesystem>
  3. #include <fstream>
  4. #include <iostream>
  5. #include <optional>
  6. #include <string>
  7. #include <string_view>
  8. #include <sstream>
  9. #include <utility>
  10. #include <vector>
  11.  
  12. using namespace std;
  13. namespace fs = std::experimental::filesystem;
  14.  
  15. [[nodiscard]] auto split_string(const string_view& input, char delimiter)
  16. {
  17.     vector<string_view> result;
  18.  
  19.     for (size_t start = 0, i = 0; i < input.size(); ++i) {
  20.         if (input[i] == delimiter) {
  21.             result.push_back({input.data() + start, i - start});
  22.             start = i + 1;
  23.         }
  24.     }
  25.  
  26.     return result;
  27. }
  28.  
  29. [[nodiscard]] optional<int> get_target_column(ifstream& input,
  30.                                               const string_view& label,
  31.                                               const char delimiter)
  32. {
  33.     string first_line;
  34.    
  35.     if (getline(input, first_line); // Init-statement for if/switch
  36.         first_line.size() == 0) { throw runtime_error("Input file missing"); }
  37.     input.seekg(0);
  38.    
  39.     auto tokens = split_string(first_line, delimiter);
  40.        
  41.     if (auto it = find(begin(tokens), end(tokens), label); // Init-statement for if/switch
  42.         it == tokens.end()) {
  43.             return {}; //return empty optional
  44.     }
  45.     else {
  46.         return distance(begin(tokens), it);
  47.     }
  48. }
  49.  
  50. [[nodiscard]] auto get_file_handlers(const string_view& input, const string_view& output)
  51. {
  52.     ifstream in_file {input.data(), ios::in};
  53.     if (!in_file.is_open()) { throw runtime_error("Unable to open input file"); }
  54.    
  55.     ofstream out_file {output.data(), ios::out | ios::trunc};
  56.     if (!out_file.is_open()) { throw runtime_error("Unable to open output file");}
  57.    
  58.     return pair(move(in_file), move(out_file)); //Template argument deduction for class templates (no make_pair)
  59. }
  60.  
  61. void do_work(ifstream& input,
  62.              ofstream& output,
  63.              int target_index,
  64.              const string_view& new_value,
  65.              const char delimiter)
  66. {
  67.     string buffer;
  68.    
  69.     getline(input, buffer); // for the header line
  70.     output << buffer << endl;
  71.    
  72.     while (getline(input, buffer)) {
  73.         auto tokens = split_string(buffer, delimiter);
  74.         tokens[target_index] = new_value;
  75.        
  76.         bool first = true;
  77.         for (const auto &token : tokens) {
  78.             if (!first) {
  79.                 output << delimiter;
  80.             }
  81.             output << token;
  82.             first = false;
  83.         }
  84.         output << "\n";
  85.     }
  86. }
  87.  
  88. [[noreturn]] void usage_terminate(const string_view& progname) noexcept
  89. {
  90.     cout << "Usage: " << progname << " [IN_FILE] [COLUMN] [NEW_VALUE] [OUT_FILE]" << endl;
  91.     abort();
  92. }
  93.  
  94. int main(int argc, char* argv[])
  95. {
  96.     try
  97.     {
  98.         if (argc != 5) { throw runtime_error("Bad arguments"); }
  99.  
  100.         auto [in_file, out_file] = get_file_handlers(argv[1], argv[4]);
  101.  
  102.         string_view new_value = argv[3];
  103.         auto target_index = get_target_column(in_file, argv[2], ',');
  104.         if (target_index) {
  105.             do_work(in_file, out_file, *target_index, new_value, ',');
  106.         }
  107.         else {
  108.             throw runtime_error("Column name doesnโ€™t exist in the input file");
  109.         }
  110.     }
  111.     catch (runtime_error& e)
  112.     {
  113.         cout << e.what() << endl;
  114.         usage_terminate(argv[0]);
  115.     }
  116.    
  117.     return 0;
  118. }
  119.  
  120. //clang++ -std=c++17 main.cc -O3
Add Comment
Please, Sign In to add comment