nikolasR200 Δημοσ. 11 Ιανουαρίου 2010 Δημοσ. 11 Ιανουαρίου 2010 Προσπαθώ να φτιάξω ένα προγραμματάκι το οποίο να δέχεται κάποια strings και να τα θεωρεί έγκυρα ή όχι.. συγκεκριμένα του εισάγω χ και y και αν ο αριθμός των y είναι ζυγός ή μηδέν να μου αναγνωρίζει το string (προς το παρόν βεβαια αναγνωρίζει και string με άλλα γράμματα αλλά αυτό θα το διορθώσω αργότερα. Το θέμα μου είναι ότι έχω βάλει ένα μετρητή n κάθε φορά που βρίσκει y να αυξάνεται κατά ένα..και στο τέλος της επανάληψης με μία if να ελέγχω αν το υπόλοιπο n%2 είναι 0 ή διάφορο του μηδενός για να μου βγάλει το αποτέλεσμα.. Το θέμα μου είναι ότι ενώ αρχικά φαίνεται να δουλεύει μετά από κάποιες επαναλήψεις βγάζει άλλα αντί άλλων στα αποτελέσματα. Χρησιμοποίησα μια εντολή cout για να ελέγξω τις τιμές του n και διαπιστώνω ότι αν σε μια επανάληψη πάρει τιμή πχ 3 στην επόμενη επανάληψη διατηρεί την τιμή παρόλο που έχω βάλει να μηδενίζεται.. Πιο συγκεκριμένα ο κώδικας είναι ο ακόλουθος >#include <iostream> #include <cstring> #include <cstdio> using namespace std; int main() { int i,n; char str[80]; do{ str[0]=0; cout << "Enter a string containing only x and y\n"; cin>>str; n=0; for(i=0; i<80; i++){ if(str[i]=='y'){ n=n+1; cout<<n<<'\n'; };}; if (n%2!=0) cout<<"String not recognized\n"; else cout << "String recognized\n"; n=0; }while(strcmp(str,"quit")); system("pause"); return 0; } αν βλέπει κανένας το λάθος ή μπορεί να βοηθήσει..
ippo00 Δημοσ. 11 Ιανουαρίου 2010 Δημοσ. 11 Ιανουαρίου 2010 Λοιπόν άκου, το indentation σου είναι misleading και δεν θα 'πρεπε να χρησιμοποιείς ποτέ do-while μιας και θα γεμίζεις τα προγράμματα σου με bugs έτσι (κάνει έλεγχο και στο quit). for(i=0; i<80; i++) πρέπει να γίνει for(i=0; '\0' != str; i++) Μιας και κάνεις iterate έξω από το string σου. Δεν βλέπω το n ν διατηρεί καμια προηγούμενη τιμή όπως λες
yourse.gr Δημοσ. 11 Ιανουαρίου 2010 Δημοσ. 11 Ιανουαρίου 2010 βάλε >#include <cstdlib> για να κάνει compile ο κώδικάς σου. Από εκεί και πέρα καλό θα ήταν να ακολουθήσεις και τις συμβουλές του ippo00 τουλάχιστον όσο αφορά το indentation.
nikolasR200 Δημοσ. 11 Ιανουαρίου 2010 Μέλος Δημοσ. 11 Ιανουαρίου 2010 Λοιπόν άκου, το indentation σου είναι misleading και δεν θα 'πρεπε να χρησιμοποιείς ποτέ do-while μιας και θα γεμίζεις τα προγράμματα σου με bugs έτσι (κάνει έλεγχο και στο quit). for(i=0; i<80; i++) πρέπει να γίνει for(i=0; '\0' != str; i++) Μιας και κάνεις iterate έξω από το string σου. Δεν βλέπω το n ν διατηρεί καμια προηγούμενη τιμή όπως λες Για το do-while η αλήθεια είναι ότι αν και σε βιβλίο που διαβάζω περί της c++ δεν ενθαρρύνεται η χρήση του το'χω δει σε αρκετά προγράμματα να χρησιμοποιείται ειδικά αν θες να υπάρχει τουλάχιστον μια επανάληψη του κώδικα σου. Σχετικά με το n που σου λέω, (υποθέτω το έκανες compile για να το δοκιμάσεις) αν βάλεις πχ είσοδο xyxyxy θα σου βγάλει σωστά το n 1,2,3 και αν στο καπάκι εισάγεις xyxy θα σου βγάλει πάλι 1,2,3 αντί 1,2.. Δοκίμασα την αλλαγή που πρότεινες for(i=0; '\0' != str; i++) και το n "φαίνεται" να συμπεριφέρεται σωστά..! Να είμαι ειλικρινής δε καταλαβαίνω πως σχετίζεται η τιμή του i με το ότι το n διατηρούσε την προηγούμενη μεγαλύτερη τιμή στην εκτέλεση του, πάντως φαίνεται να τρέχει σωστά..!!! Μπορείς να μου εξηγήσεις, αφού σε ευχαριστήσω για το ενδιαφέρον και τη λύση, γιατί πιστεύεις ότι το '\0' != str; έλυσε το πρόβλημα? Γιατί για να είμαι ειλικρινής με άφησε λίγο μ****α yourse.gr ο κώδικας μου κάνει compile, η προσθήκη της βιβλιοθήκης <cstdlib> σε τι θα χρησιμεύσει παραπάνω..? κατάλαβα για ποιο λόγο τελικά η αλλαγή στον κώδικα έλυσε το πρόβλημα..Δεν ήξερα ότι παραμένουν στο πίνακα σκουπίδια από προηγούμενη εκτέλεση που όμως τα μέτραγε το n... :s
ippo00 Δημοσ. 11 Ιανουαρίου 2010 Δημοσ. 11 Ιανουαρίου 2010 Για το do-while άμα το έκανες με while πάλι θα εκτελούνταν έστω μια φορά εκτός αν αρχικοποιούσες το str με quit... Το φαιδρό είναι ότι ο κόσμος δεν διδάσκει goto επιδή 'μπλέκει' τον κώδικα αλλά διδάσκει do - while που έχει την τάση γεννά bugs... whatever, shoot yourself in the foot. Όσο για την ερώτηση σου την απαντάς (Οο) οπότε υποθέτω ότι έκανες edit..
nikolasR200 Δημοσ. 12 Ιανουαρίου 2010 Μέλος Δημοσ. 12 Ιανουαρίου 2010 Ναι μου εξήγησε ένας φίλος ότι όταν εισάγω εγώ νέο string από το προηγούμενο (ενδεχομένως μεγαλύτερο) παραμένουν οι θέσεις πίνακα που περισσεύουν με αποτέλεσμα να συμπεριφέρεται το n όπως είπα. Ενώ με το δικό σου, με το που διαβάζει το κενό χαρακτήρα που είναι το τέλος κάθε string τερματίζει τη for πολύ σωστός..!! Να προσθέσω τώρα άλλη μία ερώτηση..Γίνεται τον πίνακα str[80] να τον κάνω "ακαθόριστου" μεγέθους? δλδ str[] και να μπορώ να εισάγω όσο μεγάλο string θέλω? Μου προτάθηκε μία λύση με χρήση string σαν μεταβλητή με τη βοήθεια κλάσεων χωρίς πίνακα, απλά αναρρωτιόμουν αν μπορεί να υλοποιηθεί και στο δικό μου εγχείρημα που έχω χρησιμοποιήσει πίνακα..!!
Evgenios1 Δημοσ. 12 Ιανουαρίου 2010 Δημοσ. 12 Ιανουαρίου 2010 Αφου εισαι σε c++ γιατι δεν χρησιμοποιεις τη κλαση string?
ippo00 Δημοσ. 12 Ιανουαρίου 2010 Δημοσ. 12 Ιανουαρίου 2010 Ναι και όχι νικ. Είναι νωρίς ακόμα να βλέκεις
bxenos Δημοσ. 12 Ιανουαρίου 2010 Δημοσ. 12 Ιανουαρίου 2010 ...δεν θα 'πρεπε να χρησιμοποιείς ποτέ do-while μιας και θα γεμίζεις τα προγράμματα σου με bugs έτσι (κάνει έλεγχο και στο quit).... δεν το κατάλαβα αυτό. το do-while κάνει έλεγχο μόνο στο τέλος, τι ενοείς και στο quit; Για τα Goto πράγματι πολλές φορες είναι καλύτερο ένα goto παρά ένα σωρο ακατανόητα flags/if/else για να βγείς απο loop ή συνάρτηση
ippo00 Δημοσ. 12 Ιανουαρίου 2010 Δημοσ. 12 Ιανουαρίου 2010 δεν το κατάλαβα αυτό.το do-while κάνει έλεγχο μόνο στο τέλος, τι ενοείς και στο quit; Για τα Goto πράγματι πολλές φορες είναι καλύτερο ένα goto παρά ένα σωρο ακατανόητα flags/if/else για να βγείς απο loop ή συνάρτηση 'Ηθελα να πω ότι τρέχει όλο το code block, ελέχει το 'quit' string για χ και y. Γενικά δεν είναι καλή idea να τρέξεις code unconditionally με το σκεπτικό "μια φορά.. και μετά βλέπουμε.."
nikolasR200 Δημοσ. 12 Ιανουαρίου 2010 Μέλος Δημοσ. 12 Ιανουαρίου 2010 Αφου εισαι σε c++ γιατι δεν χρησιμοποιεις τη κλαση string? Αυτό μου πρότειναν, ίσως δεν το περιέγραψα σωστά παραπάνω, απλά επειδή δεν μου είναι ακόμα ιδιαίτερα οικεία, σκεφτόμουν αν μπορεί να γίνει στην λύση που έχω φτιάξει εγώ με τον πίνακα..Αν και απ'ότι καταλαβαίνω, για να γίνει δυναμικό έχει πολύ μπλέξιμο..!
bxenos Δημοσ. 12 Ιανουαρίου 2010 Δημοσ. 12 Ιανουαρίου 2010 ...Γενικά δεν είναι καλή idea να τρέξεις code unconditionally με το σκεπτικό "μια φορά.. και μετά βλέπουμε.." Απόψεις είναι αυτές. Εγω δεν συμφωνώ ούτε με το "γενικα δεν είναι καλή ιδεα". Και το while και το do-while είναι ξεκάθαρο τι κάνουν. Ο καθένας διαλέγει πως θα δουλεύει. ---------- Προσθήκη στις 22:13 ---------- Προηγούμενο μήνυμα στις 22:11 ---------- ... απλά επειδή δεν μου είναι ακόμα ιδιαίτερα οικεία, σκεφτόμουν αν μπορεί να γίνει στην λύση που έχω φτιάξει εγώ με τον πίνακα... τωρα στο ξεκίνημα μπορείς να το δοκιμάσεις και με πίνακα, αλλά να ξέρεις ότι η λογική της C++ είναι να αποφεύγεις τους πινακες και να χρησιμοποιείς αντικείμενα οπως το vector για τέτοιες δουλείες που έχουν επιπλεον προστασίες σε περίπτωση προγραμματιστικου λάθους.
jstark Δημοσ. 12 Ιανουαρίου 2010 Δημοσ. 12 Ιανουαρίου 2010 Πάρε μία όχι και τόσο καλή λύση με αρκετά -if- > #include <iostream> #include <string> #include <algorithm> struct check_str_and_count_y { check_str_and_count_y(int &ys, int &chk) : ys_(ys), chk_(chk) {} void operator()(char c) { if (c == 'y') { ++ys_; } else if (c != 'x') { chk_ = 0; } } int &ys_; int &chk_; }; int main(int argc, char *argv[]) { std::string str; int chk, ynum; while (std::cin >> str) { chk = 1; ynum = 0; std::for_each(str.begin(), str.end(), check_str_and_count_y(ynum, chk)); if (!chk) { std::cout << "ERROR! STRING -> '" << str << "' NOT VALID!\n"; } else if (!ynum || ynum % 2 == 0) { std::cout << "SUCCESS for STRING: " << str << "\n"; } else { std::cout << "FAILURE for STRING: '" << str << "'\n"; } } return 0; } Το σημείο (for_each) που μάλλον θα σου φανεί ακατανόητο μπορείς να το αλλάξεις με μία απλή συνάρτηση που θα φτιάξεις εσύ και θα ελέγχει το str. Ετσι δε θα χρειαστεί και το #include <algorithm> αλλά ούτε και την κλάση check_str_and_count_y. Σου προτείνω να το κάνεις ώστε να απλοποιήσεις ακόμη περισσότερο τον κώδικα.
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.