C++ obiektowo - usuwanie jednej linii

0

Witam, rozpocząłem dziś naukę C++ obiektowo (kurs Mirosława Zelenta) i na końcu odcinka polecono wykonać proste zadanie domowe z programowania obiektowego. Trzeba dodać obiekty do "bazy". Wszystko szło pięknie, do momentu gdy zechciałem wpisać z klawiatury kilka wyrazów oddzielonych od siebie spacją. W przypadku wywołania funkcji na rzecz pierwszego obiektu wszystko idzie zgodnie z planem, lecz przy dodawaniu drugiego obiektu ucina mi pierwszą linię do wpisania, efekt jak na załączniku.
A tutaj kod:

#include <iostream>

using namespace std;

class Samochod
{
public:

    string marka;
    string model;
    int rocznik;
    int przebieg;

    void wczytaj()
    {
        cout<<"DODAWANIE NOWEGO SAMOCHODU DO BAZY"<<endl<<endl;
        cout<<"Podaj marke samochodu: "<<endl;
        getline(cin,marka);
        cout<<"Podaj model samochodu: "<<endl;
        getline(cin,model);
        cout<<"Podaj rocznik samochodu: "<<endl;
        while(!(cin>>rocznik))
        {
        cout << "To nie jest liczba! Podaj prawidlowa wartosc: ";
        cin.clear();
        cin.ignore(9999, '\n');
        }
        cout<<"Podaj przebieg samochodu: "<<endl;
        while(!(cin>>przebieg))
        {
        cout<<"To nie jest liczba! Podaj prawidlowa wartosc!: ";
        cin.clear();
        cin.ignore(9999, '\n');
        }
    }

    void wypisz()
    {
        cout<<endl<<"Marka samochodu to: "<<marka<<endl;
        cout<<"Model tego samochodu to: "<<model<<endl;
        cout<<"Rocznik tego samochodu to: "<<rocznik<<endl;
        cout<<"Przebieg tego samochodu wynosi: "<<przebieg<<endl<<endl;
    }
};

int main()
{
    Samochod s1;
    s1.wczytaj();
    s1.wypisz();

    Samochod s2;
    s2.wczytaj();
    s2.wypisz();
}
0

Zastąp getLine(cin, XXX); na po prostu cin >> XXX; i będzie hulać.

0

dodaj cin.get() przed getline pobierającego markę samochodu.

0
MasterBLB napisał(a):

Zastąp getLine(cin, XXX); na po prostu cin >> XXX; i będzie hulać.

Jak zastąpię getline cinem, to dwa osobne wyrazy zapisuje mi do dwóch komórek, do marki a potem modelu :/

Sunnydev napisał(a):

dodaj cin.get() przed getline pobierającego markę samochodu.

rozumiem, żę mam zastąpić getline funkcją cin.get()? W takim przypadku w drugim wywołaniu tej funkcji od razu przechodzi do 3ciej linii, gdzie mam wpisać rocznik :/

1

@Mefix Nie, miałeś go wrzucić przed getline(cin,marka); w swojej funkcji, ale okazało się, że ucina pierwszy znak, a więc wrzuć cin.get(); przed obiekt s2 w mainie(). Teraz będzie wporzo.

0
Sunnydev napisał(a):

@Mefix Nie, miałeś go wrzucić przed getline(cin,marka); w swojej funkcji, ale okazało się, że ucina pierwszy znak, a więc wrzuć cin.get(); przed obiekt s2 w mainie(). Teraz będzie wporzo.

Działa, dzięki. Zastanawia mnie tylko, dlaczego nie mogę tej opcji wykorzystać bezpośrednio w funkcji void wczytaj(), tak żeby nie ucięło ostatniego znaku

YooSy napisał(a):

http://cpp0x.pl/kursy/Kurs-C++/FAQ/std-getline-mi-nie-dziala!/594

Dzięki, przejrzałem, w przypadku dodania linii

std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );

w konsoli muszę wpisywać po dwa razy markę i model samochodu.

0

Pokaż aktualny kod. Ważna jest kolejność instrukcji i trzeba pamiętać, że metoda ignore() będzie czekać na podanie czegokolwiek do zignorowania, gdy bufor strumienia będzie pusty.

0
YooSy napisał(a):

Pokaż aktualny kod. Ważna jest kolejność instrukcji i trzeba pamiętać, że metoda ignore() będzie czekać na podanie czegokolwiek do zignorowania, gdy bufor strumienia będzie pusty.

#include <iostream>
#include <limits>

using namespace std;

class Samochod
{
public:

    string marka;
    string model;
    int rocznik;
    int przebieg;

    void wczytaj()
    {
        cout<<"DODAWANIE NOWEGO SAMOCHODU DO BAZY"<<endl<<endl;
        cout<<"Podaj marke samochodu: "<<endl;
        getline(cin,marka);
        std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );
        cout<<"Podaj model samochodu: "<<endl;
        getline(cin,model);
        std::cin.ignore( std::numeric_limits < std::streamsize >::max(), '\n' );
        cout<<"Podaj rocznik samochodu: "<<endl;
        while(!(cin>>rocznik))
        {
        cout << "To nie jest liczba! Podaj prawidlowa wartosc: ";
        cin.clear();
        cin.ignore(9999, '\n');
        }
        cout<<"Podaj przebieg samochodu: "<<endl;
        while(!(cin>>przebieg))
        {
        cout<<"To nie jest liczba! Podaj prawidlowa wartosc!: ";
        cin.clear();
        cin.ignore(9999, '\n');
        }
    }

    void wypisz()
    {
        cout<<endl<<"Marka samochodu to: "<<marka<<endl;
        cout<<"Model tego samochodu to: "<<model<<endl;
        cout<<"Rocznik tego samochodu to: "<<rocznik<<endl;
        cout<<"Przebieg tego samochodu wynosi: "<<przebieg<<endl<<endl;
    }
};

int main()
{
    Samochod s1;
    s1.wczytaj();
    s1.wypisz();

    Samochod s2;
    //cin.get();
    s2.wczytaj();
    s2.wypisz();
}

1
#include <iostream>
#include <string>
#include <limits>

using namespace std;

class Samochod
{
private:

	string marka;
	string model;
	int rocznik;
	int przebieg;

public:
	void wczytaj()
	{
		cout << "DODAWANIE NOWEGO SAMOCHODU DO BAZY" << endl << endl;
		cout << "Podaj marke samochodu: " << endl;
		getline(cin, marka);
		cout << "Podaj model samochodu: " << endl;
		getline(cin, model);
		cout << "Podaj rocznik samochodu: " << endl;
		rocznik = WezLiczbe();
		cout << "Podaj przebieg samochodu: " << endl;
		przebieg = WezLiczbe();
	}

	void wypisz()
	{
		cout << endl << "Marka samochodu to: " << marka << endl;
		cout << "Model tego samochodu to: " << model << endl;
		cout << "Rocznik tego samochodu to: " << rocznik << endl;
		cout << "Przebieg tego samochodu wynosi: " << przebieg << endl << endl;
	}

private:
	int WezLiczbe() {
		int n;
		while (!(std::cin >> n)) {
			std::cin.clear();
			std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
			cout << "To nie jest liczba! Podaj prawidlowa wartosc: ";
		}
		std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
		return n;
	}
};

int main()
{
	Samochod s1;
	s1.wczytaj();
	s1.wypisz();

	Samochod s2;
	s2.wczytaj();
	s2.wypisz();
}

Korzystając z std::string dodawaj plik nagłówkowy, w którym klasa jest zdefiniowana (<string>). Wiem, że niektóre implementacje dodają tą klasę pośrednio,
ale to jest zły nawyk i w innej implementacji kompilatora kod może nie zadziałać.

0

Dzięki, działają oba sposoby, Twój oraz Sunnydev, teraz pozostaje dokładnie zrozumieć co zrobił każdy z nich :p

1

operator>> po użyciu pozostawia w buforze strumienia znak nowej linii, a std::getline ma trzeci argument, którym domyślnie jest \n.
Po wczytaniu liczby std::getline odczytuje od razu '\n' i kończy odczytywanie danych.
https://en.cppreference.com/w/cpp/string/basic_string/getline

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