lion2486 Δημοσ. 16 Νοεμβρίου 2013 Δημοσ. 16 Νοεμβρίου 2013 Υ.Γ.: Αν το θες μόνο για Windows Βάλε Conio για να μην χρειάζεται Enter (αν σε ενδιαφέρει)..
migf1 Δημοσ. 17 Νοεμβρίου 2013 Δημοσ. 17 Νοεμβρίου 2013 (επεξεργασμένο) #include <stdio.h> #define MAXBUFSIZE 5+1 // ----------------------------------------------------------------------- int main( void ) { char buffer[MAXBUFSIZE] = {'\0'}; int h = 0, m = 0; // hours, minutes for (; { printf("Enter time in 24h format (e.g.: 23:45): "); fflush(stdout); fgets(buffer, MAXBUFSIZE, stdin); // if buffer-overflow attempted, flush the stdin if ('\0' != buffer[MAXBUFSIZE-2] && '\n' != buffer[MAXBUFSIZE-2] ){ while ('\n' != getchar() ) ; // void } // demand valid input if ( 2 != sscanf(buffer, "%d:%d", &h, &m) || h < 0 || h > 24 || m < 0 || m > 59 ){ puts( "Bad input, try again..." ); continue; } break; } printf( "%02d:%02d\n", h, m ); return 0; } EDIT: Διόρθωση της περίπτωσης επιχειρούμενου buffer overflow. Επεξ/σία 17 Νοεμβρίου 2013 από migf1 1
Retromaniac Δημοσ. 17 Νοεμβρίου 2013 Δημοσ. 17 Νοεμβρίου 2013 Αυτο δεν τον εμποδίζει να πατήσει ότι θέλει απλά του κάνει υπόδειξη ότι έδωσε λάθο Input.
Star_Light Δημοσ. 17 Νοεμβρίου 2013 Δημοσ. 17 Νοεμβρίου 2013 ή χρησιμοποίησε την getch() Η συναρτηση που του προτεινεις δεν ειναι φορητη.
migf1 Δημοσ. 17 Νοεμβρίου 2013 Δημοσ. 17 Νοεμβρίου 2013 Αυτο δεν τον εμποδίζει να πατήσει ότι θέλει απλά του κάνει υπόδειξη ότι έδωσε λάθο Input. Ναι, απαντάει δηλαδή στην αρχική ερώτηση του poster πως μπορεί να διαχειριστεί bad input ώστε να μην κρασάρει ο κώδικάς του. Γίνεται επίσης compile παντού μιας και είναι cross-platform, στάνταρ C... δεν περιέχει π.χ. fflush(stdin) που δουλεύει μόνο σε Windows. Απλώς τώρα που ξανακοιτάω τον κώδικα, σε περίπτωση buffer-overflow δεν τον ειδοποιεί, απλά του κόβει το περιττό input... δλδ αν του δώσει π.χ. 12:345 δεν θα παραπονεθεί κι απλώς θα κόψει το 5άρι από το τέλος (ώστε να μην κρασάρει). Επίσης δεν κάνει reset το buffer (κακό αυτό). Για να το κάνουμε λίγο πιο strict και safe μπορούμε να αυξήσουμε κατά 1 τη χωρητικότητα του buffer και να το αλλάξουμε σε κάτι τέτοιο... #include <stdio.h> #include <string.h> #define MAXBUFSIZE 6+1 // ----------------------------------------------------------------------- int main( void ) { char buffer[MAXBUFSIZE]; // = {'\0'} replaced by memset() inside the loop int h = 0, m = 0; // hours, minutes for (; { memset(buffer, '\0', MAXBUFSIZE); printf("Enter time in 24h format (e.g.: 23:45): "); fflush(stdout); fgets(buffer, MAXBUFSIZE, stdin); // if buffer-overflow detected: warn, flush the stdin and ask for new input if ('\0' != buffer[MAXBUFSIZE-2] && '\n' != buffer[MAXBUFSIZE-2] ){ puts( "*** buffer-overflow attempt detected" ) puts( "*** flushing stdin..." ); while ('\n' != getchar() ) ; // void puts("*** try again..."); continue; } // demand valid input if ( 2 != sscanf(buffer, "%d:%d", &h, &m) || h < 0 || h > 24 || m < 0 || m > 59 ){ puts( "** bad input, try again..." ); continue; } break; } printf( "%02d:%02d\n", h, m ); return 0; } 1
Retromaniac Δημοσ. 17 Νοεμβρίου 2013 Δημοσ. 17 Νοεμβρίου 2013 Γιατί να μπεις σε όλη αυτή την διαδικασία, με overflows κτλ αφού το να του επιτρεπει να πατάει μόνο ότι πρέπει είναι το καλύτερο. Ο χρήστης το ρώτησε έτσι γιατί δεν ήξερε ότι μπορούσε να γίνει και με αυτό τον τρόπο. Τώρα που το είδε δεν νομίζω να θέλει να χρησιμοποιήσει την scanf για σοβαρό input. Μόνο για πρόχειρα προγραμματάκια.
migf1 Δημοσ. 17 Νοεμβρίου 2013 Δημοσ. 17 Νοεμβρίου 2013 Ούτε εγώ χρησιμοποίησα scanf()... χρησιμοποίησα συνδυασμό fgets() με sscanf(). Προσωπικά το θεωρώ πολύ πιο βατό από το να φτιάχνει από την αρχή custom command-line editing mode.
Retromaniac Δημοσ. 17 Νοεμβρίου 2013 Δημοσ. 17 Νοεμβρίου 2013 Είναι πολύ λιγότερο user friendly. Και η ρουτίνα είναι πιο εύκολη και λιγότερο δύσκολο να έχεις κάποιο λάθος. Εγώ την έφτιαξα χωρίς compiler και έχοντας να γράψω c και c++ 8 χρόνια.
migf1 Δημοσ. 17 Νοεμβρίου 2013 Δημοσ. 17 Νοεμβρίου 2013 Διαφωνώ! 3 γραμμές definitions... #define MAXBUFSIZE ... char buffer[MAXBUFSIZE]; int n=0, temp; 2 γραμμές είσοδος... if ( fgets(buffer, MAXBUFSIZE, stdin) ) { n = sscanf(buffer, "...", ...); 5 γραμμές για stdin flushing & απόρριψη τελικού ENTER ελέω fgets()... temp = strlen(buffer); if (temp > 0) --temp; if ( '\n' != buffer[temp] ) while ('\n' != getchar() ) ; /* flush stdin */ buffer[temp] = '\0'; // reject trailing '\n' or extra input } Όσες έξτρα γραμμές χρειάζεσαι για input validation συγκεκριμένα για τον κώδικά σου (το overflow το κάνει handle έτσι κι αλλιώς η fgets()... εμείς απλά το κάναμε detect απλά και μόνο για να φλασάρουμε τα σκουπίδια από την κύρια είσοδο) if ( n != number_of_args_passed_in_sscanf /* put here code specific extra checks */ ) { /* error */ } Σύνολο: 10 γραμμές + όσους custom ελέγχους χρειάζεται ο εκάστοτε κώδικαςγια μια στανταρισμένη μεθοδολογία που δουλεύει σε όλες τις πλατφόρμες, και για τη συντριπτική πλειοψηφία των input από command-line οποιουδήποτε προγράμματος. Crossplatform user-friendly και στανταρισμένα λιγότερο επιρρεπής σε λάθη. 1
Retromaniac Δημοσ. 17 Νοεμβρίου 2013 Δημοσ. 17 Νοεμβρίου 2013 Τέλεια. Μια ρουτίνα που σε αφήνει να γράψεις όσο θέλεις και ότι θέλεις και μετά validate. Και όλα αυτά το 2013....
Star_Light Δημοσ. 17 Νοεμβρίου 2013 Δημοσ. 17 Νοεμβρίου 2013 μιγφ1 αφου τον βλεπεις οτι ειναι πνευμα αντιλογιας τι το συνεχιζεις? σορρυ κιολας για την παρεμβαση.
migf1 Δημοσ. 17 Νοεμβρίου 2013 Δημοσ. 17 Νοεμβρίου 2013 Μάλιστα, από ότι κατάλαβα κατά την άποψή σου το 2013 η ενδεδειγμένη μέθοδος εισόδου από την γραμμή εντολών είναι να γράφεις ξεχωριστό char-based command-line editing mode για κάθε διαφορετικό input type που χρειάζεται το πρόγραμμά σου. Δηλαδή αν έχεις 20 διαφορετικά input types στο πρόγραμμά σου θα γράψεις 20 διαφορετικά editing-modes ελέγχοντας έναν-έναν τον κάθε χαρακτήρα με μια σειρά από if (nested or not) για τον κάθε χαρακτήρα! Κι όλα αυτά με κώδικα που τρέχει μόνο σε Windows. Προφανώς έχω μείνει πολύ πίσω!
Star_Light Δημοσ. 17 Νοεμβρίου 2013 Δημοσ. 17 Νοεμβρίου 2013 Μάλιστα, από ότι κατάλαβα κατά την άποψή σου το 2013 η ενδεδειγμένη μέθοδος εισόδου από την γραμμή εντολών είναι να γράφεις ξεχωριστό char-based command-line editing mode για κάθε διαφορετικό input type που χρειάζεται το πρόγραμμά σου. Δηλαδή αν έχεις 20 διαφορετικά input types στο πρόγραμμά σου θα γράψεις 20 διαφορετικά editing-modes ελέγχοντας έναν-έναν τον κάθε χαρακτήρα. Κι όλα αυτά με κώδικα που τρέχει μόνο σε Windows. Προφανώς έχω μείνει πολύ πίσω! Σε παρακαλώ σημασια έχει MONO ο αλγοριθμος ασχετα αμα αυτος που ανοιξε το θεμα το ζητησε σε C. Και ο φιλος του προτεινε συναρτηση η οποια δεν ειναι portable.
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα