In case of parsing failures, you were previously returning an empty ConfigUnit. I have shown a, probably cleaner alternative, using C++17 std::optional.
#include <functional>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
struct config_unit {
std::string parameter;
std::string value;
friend std::ostream& operator<<(std::ostream& ostream, const config_unit& cu) {
return ostream << "Parameter: '" << cu.parameter << "'\t"
<< "Value: '" << cu.value << "'" << '\n';
}
};
std::optional<config_unit> get_config_unit(const std::string& line) {
std::istringstream ss(line);
std::string field;
std::vector<std::string> fields;
while (getline(ss, field, ' ')) fields.push_back(field);
if (fields.size() != 2) return std::nullopt;
return config_unit{fields[0], fields[1]};
}
int main() {
std::string filename{"music.txt"};
std::ifstream fstream(filename, std::ios_base::in);
if (fstream.fail()) {
std::cerr << "couldn't open file '" << filename << "\n";
return EXIT_FAILURE;
}
std::string line;
while (std::getline(fstream, line)) {
auto maybe_unit = get_config_unit(line);
if (maybe_unit) std::cout << *maybe_unit;
}
return EXIT_SUCCESS;
}