Problem ze strumieniem cin

0

Mam do napisania program, który wczytuje imiona i pyta użytkownika ile te osoby mają lat a następnie drukuje wynik. Problem polega na tym, że po wczytaniu imion do wektora program nie pyta użytkownika o imiona tylko wsadza głupie wartości do zmiennych double.

Kod:

#include <algorithm>
#include <iostream>
#include <vector>
#include <string>
#include <stdexcept>

using namespace std;

inline void error(const string& errmsg) {
    throw runtime_error(errmsg);
}

class Name_pairs {
public:
    void read_names();
    void read_ages();
    void print() const;
    void sort();

private:
    vector<string> names;
    vector<double> ages;
};

void Name_pairs::read_names() {
    cout << "Podaj imiona: ";
    string name;
    while (cin >> name) {
        names.push_back(name);
    }
}

void Name_pairs::read_ages() {
    for (int i = 0; i < names.size(); ++i) {
        cout << "Podaj wiek dla imienia " << names[i] << ": ";
        double age;
        cin >> age;
        ages.push_back(age);
    }
}

void Name_pairs::print() const {
    if (names.size() != ages.size()) {
        error("wektory names i ages muszą być równe");
    }
    for (int i = 0; i < names.size(); ++i) {
        cout << names[i] << " -> " << ages[i] << '\n';
    }
}

void Name_pairs::sort() {
    if (names.size() != ages.size()) {
        error("wektory names i ages muszą być równe");
    }
    vector<string> names_copy(names);
    vector<double> ages_copy(ages);
    std::sort(names.begin(), names.end());
    for (int i = 0; i < names.size(); ++i) {
        for (int j = 0; j < names.size(); ++j) {
            if (names[i] == names_copy[j]) {
                ages[i] = ages_copy[j];
            }
        }
    }
}

int main() {
    Name_pairs pairs;
    pairs.read_names();
    pairs.read_ages();
    pairs.print();
    pairs.sort();
    pairs.print();
    return 0;
}

Wynik:

Podaj imiona: Marta Helena Alina
Podaj wiek dla imienia Marta: Podaj wiek dla imienia Helena: Podaj wiek dla imienia Alina: Marta -> 6.95279e-310
Helena -> 6.95279e-310
Alina -> 6.95279e-310
Alina -> 6.95279e-310
Helena -> 6.95279e-310
Marta -> 6.95279e-310

Próbowałem użyć wywołania cin.clear() i cin.ignore(numeric_limits<streamsize>::max(), '\n') przed double age; cin >> age; ale to nic nie dało.

0
    while (cin >> name) {
        names.push_back(name);
    }

wczytujesz imiona aż do końca strumienia, więc nie rozumiem zaskoczenia.

0

Zrób to normalnie, tak by łatwo wprowadzać dane:

    while (cin >> name >> age) {
        namesAge.emplace_back(name, age);
    }
0

Zadanie polega na tym by to zrobić w dwóch osobnych funkcjach.

0
Garydos392 napisał(a):

Zadanie polega na tym by to zrobić w dwóch osobnych funkcjach.

podaj dokładną treść zadania.

0

Dobra zrobiłem to w ten sposób:

void Name_pairs::read_names() {
    cout << "Ile imion chcesz wczytać? ";
    int n;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cout << "Podaj imię nr " << i << ": ";
        string name;
        cin >> name;
        names.push_back(name);
    }
}

Treść zadania brzmi: zaprojektuj i zaimplementuj klasę Name_pairs przechowującą pary (imię, wiek), gdzie imię jest łańcuchem, a wiek typu double. Do reprezentacji tych par użyj wektorów składowych vector<string> (o nazwie name) i vector<double> (o nazwie age). Zaimplementuj operacje wejściowe o nazwach read_names() (wczytującą serię imion) i read_ages() (proszącą użytkownika o podanie wieku dla każdego imienia). Napisz funkcję print() drukującą pary (name[i], age[i]) (po jednej na wiersz). Napisz operację sort() sortującą wektor name w kolejności alfabetycznej i odpowiednio w związku z tym zmianiającą kolejność elementów w wektorze age. Wszystkie operacje zaimplementuj jako funkcje składowe. Przetestuj klasę (oczywiście testy zacznij przeprowadzać wcześnie i rób to często).

2
Garydos392 napisał(a):

Treść zadania brzmi: zaprojektuj i zaimplementuj klasę Name_pairs przechowującą pary (imię, wiek), gdzie imię jest łańcuchem, a wiek typu double. Do reprezentacji tych par użyj wektorów składowych vector<string> (o nazwie name) i vector<double> (o nazwie age). Zaimplementuj operacje wejściowe o nazwach read_names() (wczytującą serię imion) i read_ages() (proszącą użytkownika o podanie wieku dla każdego imienia). Napisz funkcję print() drukującą pary (name[i], age[i]) (po jednej na wiersz). Napisz operację sort() sortującą wektor name w kolejności alfabetycznej i odpowiednio w związku z tym zmianiającą kolejność elementów w wektorze age. Wszystkie operacje zaimplementuj jako funkcje składowe. Przetestuj klasę (oczywiście testy zacznij przeprowadzać wcześnie i rób to często).

Po treści zadania widzę: prowadził ślepy kulawego.

Ja bym obszedł durne wymagania tak:

void Name_pairs::read_names() {
    cout << "Podaj imiona w osobnych liniach (pusta linia kończy wprowadzanie):";
    std::string name;
    while(std::getline(std::cin, name) && !name.empty()) {
        names.push_back(name);
        cout << "Podaj następne:";
    }
}

void Name_pairs::read_ages() {
     ages.clear();
     ages.reserve(names.size());
     for (const auto& name : names) {
          std::cout << "Podaj wiek dla " << name << ": ";
          double age;
          while (!(std::cin >> age)) {
               std::cin.clear();
               std::cin.ignore(std::numeric_limits<streamsize>::max(), '\n');
               std::cout << "Nieprawidłowa wartość podaj jeszcze raz wiek dla " << name << ": ";
          }
          ages.push_back(age);
     }
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1