Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Καλησπερα, εχω μια ασκηση οπου περιμενω απο τον χρηστη να μου δωσει ενα string και ενα int το οποιο string ειναι ονοματα λαχανικων, και το int τα κιλα τους και τα αποθηκευω σε ενα vector.

 

Εχω φτιαξει αυτο:

 

    vector<string> groceries;
    vector<int> kg;
    string groc;
    int kilo;

 

    while(cin>>groc>>kilo && groc!="q q")
    {
    groceries.push_back(groc);
    kg.push_back(kilo);
    }
  

 

Οταν δωθει το "q q" πρεπει το προγραμμα να τερματιζει την εισαγωγη και να προχωραει παρακατω, το προβλημα που αντιμετωπιζω ειναι το πως θα καθορισω το προγραμμα ωστε οταν ο χρηστης βαζει στα κιλα κατι διαφορετικο απο αριθμο, να μην αποτυγχανει το προγραμμα και να τερματιζει αλλα να την ξαναζηταει την εισαγωγη;

 

Ψαχνω μια απλη λυση διοτι εχω κοιταξει και στο google αλλα λογω του οτι ειναι ασκηση της σχολης μου δεν υπαρχει λογος να αντιγραψω κατι ειδικα και απο τη στιγμη που δεν το εχουμε διδαχθει.

 

Αρα δεν ζηταω να μου πειτε την λυση, καποια ιδεα ισως;

Δημοσ.

Χμμ.. Θα μπορούσες να αποθηκεύεις και τα 2 σαν συμβολοσειρές και μετά να ελέγχεις ότι η δεύτερη αποτελείται μόνο απο ψηφία και να την μετατρέψεις σε αριθμό.

Δημοσ.

Αυτό που είπε ο lion. 

 

Επισης και αναλογα ποσο αυστηρός ειναι ο εξεταστής, να ελεγχεις και αν η ονομασια του λαχανικου εχει κενό (π.χ. laxanakia vrikselon) γιατί και πάλι θα χτυπά error (π.χ. laxanakia vrikselon 6)

Δημοσ.

Βασικα δεν θα ήθελα να βάλω μια αυθαιρετη τιμή για να ελεγχω. Όπως επίσης μας είπαν οι βοηθοί ότι δεν χρειάζεται να αναλωθουμε τώρα στην αρχή για να ελεγξουμε και τα ονόματα κλπ μόνο σε λογικά πλαισια.

Δημοσ.

πως θα καθορισω το προγραμμα ωστε οταν ο χρηστης βαζει στα κιλα κατι διαφορετικο απο αριθμο, να μην αποτυγχανει το προγραμμα και να τερματιζει αλλα να την ξαναζηταει την εισαγωγη;

 

Σημαντικό: έχεις καταλάβει ακριβώς γιατί τερματίζει το πρόγραμμα αν δώσεις βλακείες για αριθμό; Αν το καταλάβεις τότε η απάντηση αρχίζει να εμφανίζεται μόνη της.

 

Ο σωστός C++ τρόπος είναι κάτι σαν το παρακάτω:

do {
    if (!(cin >> groc) || groc == "q q") break; // τέλος εισόδου, π.χ. χαρακτήρας EOF ή "q q"

    if (!(cin >> kilo)) { // σφάλμα γιατί πήραμε βλακείες αντί για νούμερο
        cin.clear(); // ας υποθέσουμε ότι δεν πήραμε βλακείες
        cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // και ας τις σβήσουμε από τον buffer εισόδου
        continue; // και πάμε από την αρχή
    }

    groceries.push_back(groc);
    kg.push_back(kilo);

} while (true);
Δημοσ. (επεξεργασμένο)

Το εχω καταλαβει εκει που κολλαω ειναι στο cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

 

το οποιο δεν καταλαβαινω ακριβως τι κανει διοτι δεν το εχουμε διδαχθει.

 

EDIT : Μου ειπαν εκ των βοηθων οτι δεν χρειαζεται καθολου να ελεγξουμε αυτην την περιπτωση της λαθος εισαγωγης δηλαδη, οποτε απλα προσπαθω μολις γινει η λαθος εισαγωγη να εκτυπωσω οτι εγινε λαθος και τερματιζει το προγραμμα.

 

Χρησιμοποιω αυτο:

    if(!(kilo))
    {
    cout<<"Only numbers-integers allowed, program terminating";
    }

Αλλα δεν δουλευει οπου κι αν το βαλω ειτε μεσα στην while ειτε απο εξω μετα απο αυτην. Γιατι συμβαινει αυτο;

Επεξ/σία από pavlos1908
Δημοσ.

1. Το τι κάνει το cin.ignore είναι ένα από τα πράγματα που θα πρέπει να μάθεις πώς να ανακαλύπτεις μόνος σου, αλλιώς μην υπολογίζεις να κάνεις τον προγραμματισμό επάγγελμα.

 

2. Το αν χρειάζεται κάτι για να πάρεις το βαθμό (που in the long run είναι ασήμαντος) και το αν χρειάζεται για να μάθεις πράγματα (που in the long run είναι το παν) είναι δύο διαφορετικά πράγματα.

 

3. Από τη στιγμή που γράφεις if(!kilo) δεν έχεις καταλάβει. Το σωστό είναι if (!(cin >> kilo)). Ο κώδικάς σου είχε μέσα while(cin >> groc >> kilo), και αυτό είναι που ρώτησα αν κατάλαβες πώς ακριβώς λειτουργεί.

Δημοσ.

 

Σημαντικό: έχεις καταλάβει ακριβώς γιατί τερματίζει το πρόγραμμα αν δώσεις βλακείες για αριθμό; Αν το καταλάβεις τότε η απάντηση αρχίζει να εμφανίζεται μόνη της.

 

Ο σωστός C++ τρόπος είναι κάτι σαν το παρακάτω:

do {
    if (!(cin >> groc) || groc == "q q") break; // τέλος εισόδου, π.χ. χαρακτήρας EOF ή "q q"

    if (!(cin >> kilo)) { // σφάλμα γιατί πήραμε βλακείες αντί για νούμερο
        cin.clear(); // ας υποθέσουμε ότι δεν πήραμε βλακείες
        cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // και ας τις σβήσουμε από τον buffer εισόδου
        continue; // και πάμε από την αρχή
    }

    groceries.push_back(groc);
    kg.push_back(kilo);

} while (true);

gorc == "q q" ?

Μαλλον ξεχασες ποσο ανωμαλο ειναι το std io.  :-D

Δημοσ.

2. Το αν χρειάζεται κάτι για να πάρεις το βαθμό (που in the long run είναι ασήμαντος) και το αν χρειάζεται για να μάθεις πράγματα (που in the long run είναι το παν) είναι δύο διαφορετικά πράγματα.

 

3. Από τη στιγμή που γράφεις if(!kilo) δεν έχεις καταλάβει. Το σωστό είναι if (!(cin >> kilo)). Ο κώδικάς σου είχε μέσα while(cin >> groc >> kilo), και αυτό είναι που ρώτησα αν κατάλαβες πώς ακριβώς λειτουργεί.

 

Στο 2 συμφωνουμε απολυτα.

 

Οσον αφορα το 3, μιας και απο οτι φαινεται δεν εχω καταλαβει ακριβως, θες να μου εξηγησεις;

Δημοσ.

Οσον αφορα το 3, μιας και απο οτι φαινεται δεν εχω καταλαβει ακριβως, θες να μου εξηγησεις;

cin>>var

το >> ονομαζεται right shift bitwise operator. (τι κανει; )

το cin ειναι ενα instance (τι ειναι αυτο;  ) απο το istream ( τι ειναι αυτο; ) που ειναι μια class (αυτο το ξερεις, ελπιζω :P )

εαν καταλαβες τα παραπανω, θα πεις wtf ??? πως θα κανω bitwise σε ενα object???

εδω ερχεται το operator overloading το οποιο δεν ειναι τιποτα αλλο απο το να φτιαχνεις συναρτησεις με "ιδιαιτερα" ονοματα.

πχ

std::string& operator +(std::string& str)
{
	std::cout << str;
	return str;
}

int main(int argc, char* argv[])
{
	std::string str("test");
	+ str;
	return 0;
}

αρα τι εχουμε μεχρι εδω; το cin>>var ειναι ενα καλεσμα μιας συναρτησης. Και ως συναρτηση, επιστρεφει και κατι, τι; Εαν δεις εδω κατω κατω σου λεει για return value ειναι το cin.

αρα το if( !(cin>>var) ) ειναι ιδιο με το cin>>var; if(!cin)

ομως τι ειναι το !cin; ειναι αλλο ενα cast operator overload το οποιο δεν ειναι τιποτα αλλο απο το να γραφεις μια συναρτηση με "ιδιαιτερα περιεργο" ονομα.

πχ

struct Test
{
	
	operator int()
	{
		std::cout << "test";
		return 0;
	}
};

int main(int argc, char* argv[])
{
	Test t;
	int i = t;
	return 0;
}

αρα το !cin ειναι μια συναρτηση που επιστρεφει αυτο

  • Like 3
Δημοσ.

cin>>var

το >> ονομαζεται right shift bitwise operator. (τι κανει; )

το cin ειναι ενα instance (τι ειναι αυτο;  ) απο το istream ( τι ειναι αυτο; ) που ειναι μια class (αυτο το ξερεις, ελπιζω :P )

εαν καταλαβες τα παραπανω, θα πεις wtf ??? πως θα κανω bitwise σε ενα object???

εδω ερχεται το operator overloading το οποιο δεν ειναι τιποτα αλλο απο το να φτιαχνεις συναρτησεις με "ιδιαιτερα" ονοματα.

πχ

std::string& operator +(std::string& str)
{
	std::cout << str;
	return str;
}

int main(int argc, char* argv[])
{
	std::string str("test");
	+ str;
	return 0;
}

αρα τι εχουμε μεχρι εδω; το cin>>var ειναι ενα καλεσμα μιας συναρτησης. Και ως συναρτηση, επιστρεφει και κατι, τι; Εαν δεις εδω κατω κατω σου λεει για return value ειναι το cin.

αρα το if( !(cin>>var) ) ειναι ιδιο με το cin>>var; if(!cin)

ομως τι ειναι το !cin; ειναι αλλο ενα cast operator overload το οποιο δεν ειναι τιποτα αλλο απο το να γραφεις μια συναρτηση με "ιδιαιτερα περιεργο" ονομα.

πχ

struct Test
{
	
	operator int()
	{
		std::cout << "test";
		return 0;
	}
};

int main(int argc, char* argv[])
{
	Test t;
	int i = t;
	return 0;
}

αρα το !cin ειναι μια συναρτηση που επιστρεφει αυτο

 

 

Εισ'ωραιος, thanks! :-)

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...