It's not a good idea to interleave std::getline
and operator>>
for reading an input stream. Instead, you'd better stick to using std::getline
twice here.
Something like this would do:
- Loop the input stream until you can't read two lines (use
std::getline
for this).
- Push back each reading into a
std::vector<std::pair<std::string, int>>
.
- If there's a parsing error on the overall line, just continue looping.
[Demo]
#include <charconv> // from_chars
#include <fmt/core.h>
#include <fmt/ranges.h>
#include <sstream> // istringstream
#include <system_error> // errc
#include <utility> // pair
#include <vector>
int main() {
std::istringstream iss{
"player1\n"
"1\n"
"player2\n"
"2ddd\n"
"player3\n"
"3 \n"
};
std::vector<std::pair<std::string, int>> players{};
for (std::string player{}, overall_str{};
getline(iss, player) and getline(iss, overall_str);) {
int overall{};
auto [ptr, ec] = std::from_chars(
overall_str.data(), overall_str.data() + overall_str.size(), overall);
if (ec == std::errc{}) {
players.push_back({player, overall});
} else {
fmt::print("Error parsing overall line: {}\n", overall_str);
continue;
}
}
fmt::print("{}\n", players);
}
// Outputs:
//
// [("player1", 1), ("player2", 2), ("player3", 3)]
You can strengthen the parsing of the overall line by:
- trimming the input string, and
- checking
std::from_chars
used all of the input string to convert to a number.
[Demo]
#include <boost/algorithm/string.hpp>
...
boost::algorithm::trim(overall_str);
...
if (ec == std::errc{} and ptr == overall_str.data() + overall_str.size()) {
// Outputs:
//
// Error parsing overall line: 2ddd
// [("player1", 1), ("player3", 3)]