Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <experimental/filesystem>
- #include <fstream>
- #include <iostream>
- #include <optional>
- #include <string>
- #include <string_view>
- #include <sstream>
- #include <utility>
- #include <vector>
- using namespace std;
- namespace fs = std::experimental::filesystem;
- [[nodiscard]] auto split_string(const string_view& input, char delimiter)
- {
- vector<string_view> result;
- for (size_t start = 0, i = 0; i < input.size(); ++i) {
- if (input[i] == delimiter) {
- result.push_back({input.data() + start, i - start});
- start = i + 1;
- }
- }
- return result;
- }
- [[nodiscard]] optional<int> get_target_column(ifstream& input,
- const string_view& label,
- const char delimiter)
- {
- string first_line;
- if (getline(input, first_line); // Init-statement for if/switch
- first_line.size() == 0) { throw runtime_error("Input file missing"); }
- input.seekg(0);
- auto tokens = split_string(first_line, delimiter);
- if (auto it = find(begin(tokens), end(tokens), label); // Init-statement for if/switch
- it == tokens.end()) {
- return {}; //return empty optional
- }
- else {
- return distance(begin(tokens), it);
- }
- }
- [[nodiscard]] auto get_file_handlers(const string_view& input, const string_view& output)
- {
- ifstream in_file {input.data(), ios::in};
- if (!in_file.is_open()) { throw runtime_error("Unable to open input file"); }
- ofstream out_file {output.data(), ios::out | ios::trunc};
- if (!out_file.is_open()) { throw runtime_error("Unable to open output file");}
- return pair(move(in_file), move(out_file)); //Template argument deduction for class templates (no make_pair)
- }
- void do_work(ifstream& input,
- ofstream& output,
- int target_index,
- const string_view& new_value,
- const char delimiter)
- {
- string buffer;
- getline(input, buffer); // for the header line
- output << buffer << endl;
- while (getline(input, buffer)) {
- auto tokens = split_string(buffer, delimiter);
- tokens[target_index] = new_value;
- bool first = true;
- for (const auto &token : tokens) {
- if (!first) {
- output << delimiter;
- }
- output << token;
- first = false;
- }
- output << "\n";
- }
- }
- [[noreturn]] void usage_terminate(const string_view& progname) noexcept
- {
- cout << "Usage: " << progname << " [IN_FILE] [COLUMN] [NEW_VALUE] [OUT_FILE]" << endl;
- abort();
- }
- int main(int argc, char* argv[])
- {
- try
- {
- if (argc != 5) { throw runtime_error("Bad arguments"); }
- auto [in_file, out_file] = get_file_handlers(argv[1], argv[4]);
- string_view new_value = argv[3];
- auto target_index = get_target_column(in_file, argv[2], ',');
- if (target_index) {
- do_work(in_file, out_file, *target_index, new_value, ',');
- }
- else {
- throw runtime_error("Column name doesnโt exist in the input file");
- }
- }
- catch (runtime_error& e)
- {
- cout << e.what() << endl;
- usage_terminate(argv[0]);
- }
- return 0;
- }
- //clang++ -std=c++17 main.cc -O3
Add Comment
Please, Sign In to add comment