|
|
| View previous topic :: View next topic |
| Author |
Message |
Kid The Xboxed

Gender:  Joined: 28 Sep 2006 Posts: 560 Location: really matters?
|
Posted: 01.06.2007, 20:22 Post subject: fgets(), while loops & problems.. |
|
|
| Code: | Random_Keys = (char*)malloc(Encryption_Strength*sizeof(char));
while (strcmp(Key_Acception, "No") == 0) {
for (i = 0 ; i < Encryption_Strength ; i++){
temp = (rand()%36);
Random_Keys[i] = Keys[temp];
}
printf("Key: %s will be used for the encryption\n", Random_Keys);
printf("Do you want to keep it?\n");
printf("Yes/No: ");
fgets(Key_Acception, 4, stdin);
} |
Δουλεύει κανονικά το while-loop αλλά συμπεριφέρεται σαν να μην βλέπει την fgets(). Όλες οι παραπάνω εντολές δουλεύουνε κανονικότατα, αλλά με το που φτάνει στο fgets() βγαίνει από το loop χωρίς να περιμένει κάποιο input από τον χρήστη. Αν σβήσω την fgets() το loop επαναλαμβάνεται χωρίς να σταματάει. Καμιά ιδέα για το τι φταίει?  _________________ dkalo.wordpress.com |
|
| Back to top |
|
 |
Advertisment
|
Posted: 01.06.2007, 20:22 Post subject: Advertisment |
|
|
|
|
| Back to top |
|
 |
Thinker_

Gender:  Joined: 11 Oct 2006 Posts: 104 Location: Here & there
|
Posted: 02.06.2007, 13:37 Post subject: |
|
|
Tip: Καταρχήν, προτείνω την επόμενη φορά να κανεις quote και τις δηλώσεις των μεταβλητών, γιατι μπορεί να έχει γίνει μαλακία εκει. Αν δεν θέλεις να αποκαλύψεις βέβαια ολόκληρο τον κώδικα, δοκίμασε να κόψεις το κομμάτι που προκαλεί πρόβλημα και να το μεταφέρεις σε νέο αρχείο με τα dependencies που αυτό συνεπάγεται.
Το αποτέλεσμα που περιγράφεις, τουλάχιστον από ότι βλέπω, είναι λογικό. Το loop δεν κόβεται πουθενά, απλά είναι θέμα της fgets και ο έλεγχος βγαίνει false. Αν κατάλαβα σωστά, αυτή η ιστορία γίνεται για ένα y/n που θέλεις απο τον χρήστη. Εφόσον το ρεύμα από το οποίο διαβάζεις είναι σταθερά το stdin, χρησιμοποίησε συναρτήσεις που κάνουν απο default χρήση του.
Λύση 1η: Αν θέλεις να χρησιμοποιήσεις ντε και σώνει fgets, αντικατάστησε με:
| Code: | | fgets(Key_Acception, sizeof(Key_Acception), stdin) |
(λογικά πρέπει να δουλέψει, αλλά θυμίσου οτι η οικογένεια των gets είναι επικίνδυνη γιατί μαζεύει ότι χαρακτήρα βρεί, που να έχει περισσέψει από προηγούμενη είσοδο από το stdin. Συγκεκριμένα, αν έχεις χρησιμοποιήσει κάποια άλλη προτροπή για είσοδο από το χρήστη με scanf, τότε η scanf δεν διαβάζει το \n και το αφήνει στο stdin, με αποτέλεσμα η επόμενη gets να το παραμαζεύει. Λυση-Μπάλωμα: βάλε μια άκυρη gets να μαζεύει τα σκουπίδια πριν την fgets σου)
Λύση 2η: Αλλά εγώ θα πρότεινα προτροπή (y/n) στο χρήστη και χρήση της getchar() που είναι και πιο ασφαλής απο την fgets. Τότε κανεις (c τύπου char)
μέσα στο loop, και ο έλεγχος θα είναι:
Αν δεν απατώμαι δε, ότι και να σου δώσει ο χρήστης, η getchar θα κρατήσει μόνο τον πρώτο χαρακτήρα, οπότε αν θες μπορείς να προσθέσεις έναν extra έλεγχο και να ξαναζητάς είσοδο σε περίπτωση χαρακτήρα διαφορου των y,n.
PS: Τι πρόγραμμα είναι αυτό; _________________ Catchy-smart signature goes here. Just pretend to laugh, and we're done. |
|
| Back to top |
|
 |
Kid The Xboxed

Gender:  Joined: 28 Sep 2006 Posts: 560 Location: really matters?
|
Posted: 02.06.2007, 14:23 Post subject: |
|
|
Το έχει αδειάσει το stdin αφού προηγουμένως έχω κάνει fflush(stdin).
Δεν θέλω y/n, προτιμώ "ολοκληρωμένες" λύσεις (επί της ουσίας καμία διαφορά βέβαια).
Πρόβλημα στην δήλωση των μεταβλητών δεν υπάρχει επειδή μετά την προσθήκη του fflush(stdin) εκτελείται το loop αλλά εκτελείται 1 φορά χωρίς να δουλέψει το fgets() & την δεύτερη φορά περιμένει για input.
Η αντικατάσταση που προτείνεις δεν αλλάζει κάτι αφού το size του πίνακα, είναι ορισμένο εξαρχής και δεν δημιουργείται με malloc().
Encrypter φτιάχνω Γιώργο. _________________ dkalo.wordpress.com |
|
| Back to top |
|
 |
parsifal Florumator

Gender:  Joined: 02 Oct 2006 Posts: 626 Location: Woodstock '69
|
Posted: 02.06.2007, 14:54 Post subject: |
|
|
Σε ποιο σημείο βάζεις την fflush; _________________ Gigabyte GA-965P-DS4 - C2D E6600 - 2GB DDR-II - W.D. 640GB SATA2 - Samsung SH-S203B - Gainward 7600GT - PixelView PlayTV Pro - HP Officejet 6310 - Samsung SyncMaster 2253BW
Gigabyte GA-G31MF-S2 - Celeron Dual Core E1200 - 1GB DDR-II - WD 160GB IDE + Seagate 320GB SATA2 - LiteOn LH-18A1P - Onboard Intel X3100 - TP-LINK PCI WiFi
3com Gigabit switch - Alcatel Speedtouch 585v6 - Forthnet ADSL Economy 24Mbps |
|
| Back to top |
|
 |
Thinker_

Gender:  Joined: 11 Oct 2006 Posts: 104 Location: Here & there
|
Posted: 02.06.2007, 14:58 Post subject: |
|
|
| Thinker_ wrote: | | ...θυμίσου οτι η οικογένεια των gets είναι επικίνδυνη γιατί μαζεύει ότι χαρακτήρα βρεί, που να έχει περισσέψει από προηγούμενη είσοδο από το stdin. Συγκεκριμένα, αν έχεις χρησιμοποιήσει κάποια άλλη προτροπή για είσοδο από το χρήστη με scanf, τότε η scanf δεν διαβάζει το \n και το αφήνει στο stdin, με αποτέλεσμα η επόμενη gets να το παραμαζεύει. Λυση-Μπάλωμα: βάλε μια άκυρη gets να μαζεύει τα σκουπίδια πριν την fgets σου... |
'Ισως δεν με κατάλαβες, αλλά ίσως και να φταιω εγώ που δεν το διατύπωσα απλούστερα.
Γενικά, μια προγραμματιστική τεχνική προτείνει να χρησιμοποιείς, είτε μόνο fputs(), fgets() συναρτήσεις, είτε μόνο fprintf, fscanf, (ή printf, scanf).
Η άλλη εναλλακτική είναι να χρησιμοποιείς flush techniques για να κρατάς το stdin "καθαρό".
Π.χ. αυτό που μπορεί να σου κάνει είναι να βάλεις το fflush(stdin); πριν την fgets(). Αν δεν δουλέψει και αυτό, τότε πρέπει να επιλέξεις με ποιες συναρτήσεις θέλεις να προγραμματίσεις.
That's all._ _________________ Catchy-smart signature goes here. Just pretend to laugh, and we're done. |
|
| Back to top |
|
 |
psolid_snake

Gender:  Joined: 09 Jan 2007 Posts: 211 Location: Kotsokalavryta
|
Posted: 02.06.2007, 14:59 Post subject: |
|
|
Δεν υπάρχει λόγος αφού χρησιμοποιείς ως βασικό input το πληκτρολόγιο να κάνεις fgets... Μόνο και μόνο η gets σου αρκεί!! Όπως σου είπα και χθες το προβλημα σου είναι στο έλεγχο της while!!!
Δοκίμασε μόνο με gets και όλα θα πρέπει να είναι εντάξει!!! Αν τρέξεις μόνο το συγκεκριμένο κομμάτι του κώδικα σου το πρόβλημα εντοπίζεται στην strcmp αν και η fgets έχει κάνει σωστά την δουλειά της πιο πάνω και έχει αποθηκεύσει το σωστό (yes or no) που έχει εισάγει ο χρήστης!!!
Τουλάχιστον στον κώδικα που σου έστειλα χθες όλα λειτουργούσαν σωστά με την χρήση μόνο της gets...
Άσε τους encrypter και πιάσε το MINIX ρεεεεεεεεεεε........  _________________ Και ας μην είμαστε γενναίοι... δεν υπάρχουν πιο ωραίοι!!! |
|
| Back to top |
|
 |
parsifal Florumator

Gender:  Joined: 02 Oct 2006 Posts: 626 Location: Woodstock '69
|
Posted: 02.06.2007, 15:03 Post subject: |
|
|
| psolid_snake wrote: | | Δεν υπάρχει λόγος αφού χρησιμοποιείς ως βασικό input το πληκτρολόγιο να κάνεις fgets... Μόνο και μόνο η gets σου αρκεί!! |
Wrong, wrong, wrong! Η gets είναι καλή για προγραμματισμό Α' Έτους, αλλά κατά τα άλλα, είναι απλά για τα μπάζα και ένα μόνιμο security hole, που μπορεί να οδηγήσει σε buffer overflows... _________________ Gigabyte GA-965P-DS4 - C2D E6600 - 2GB DDR-II - W.D. 640GB SATA2 - Samsung SH-S203B - Gainward 7600GT - PixelView PlayTV Pro - HP Officejet 6310 - Samsung SyncMaster 2253BW
Gigabyte GA-G31MF-S2 - Celeron Dual Core E1200 - 1GB DDR-II - WD 160GB IDE + Seagate 320GB SATA2 - LiteOn LH-18A1P - Onboard Intel X3100 - TP-LINK PCI WiFi
3com Gigabit switch - Alcatel Speedtouch 585v6 - Forthnet ADSL Economy 24Mbps |
|
| Back to top |
|
 |
Kid The Xboxed

Gender:  Joined: 28 Sep 2006 Posts: 560 Location: really matters?
|
Posted: 02.06.2007, 16:47 Post subject: |
|
|
Η gets() δημιουργεί buffer overflow εφόσον δεν ορίζεται το μέγιστο μήκος του string που θα διαβαστεί όπως πολύ σωστά είπε ο Αλέκος.
Γιώργο δεν γίνεται πλήρης αντικατάσταση της scanf() από την fgets() και αντίστροφα. Αναγκαστικά θα χρησιμοποιήσεις και τις 2. Αντίστοιχα ισχύει το ίδιο και για τις εντολές εκτύπωσης. _________________ dkalo.wordpress.com |
|
| Back to top |
|
 |
psolid_snake

Gender:  Joined: 09 Jan 2007 Posts: 211 Location: Kotsokalavryta
|
Posted: 02.06.2007, 17:23 Post subject: |
|
|
Sorry αλλά θα δημιουργηθεί buffer overflow από την gets() για να διαβάσει ένα string το πολύ μήκους 3 (yes or no) ?????????????????????????????????  _________________ Και ας μην είμαστε γενναίοι... δεν υπάρχουν πιο ωραίοι!!! |
|
| Back to top |
|
 |
parsifal Florumator

Gender:  Joined: 02 Oct 2006 Posts: 626 Location: Woodstock '69
|
Posted: 02.06.2007, 17:30 Post subject: |
|
|
| psolid_snake wrote: | Sorry αλλά θα δημιουργηθεί buffer overflow από την gets() για να διαβάσει ένα string το πολύ μήκους 3 (yes or no) ?????????????????????????????????  |
Στο συγκεκριμένο παράδειγμα, και αν υποθέσουμε ότι το εκτελέσιμο θα το χρησιμοποιεί μόνο ο Kid, όχι. Σε άλλες περιπτώσεις όμως...; _________________ Gigabyte GA-965P-DS4 - C2D E6600 - 2GB DDR-II - W.D. 640GB SATA2 - Samsung SH-S203B - Gainward 7600GT - PixelView PlayTV Pro - HP Officejet 6310 - Samsung SyncMaster 2253BW
Gigabyte GA-G31MF-S2 - Celeron Dual Core E1200 - 1GB DDR-II - WD 160GB IDE + Seagate 320GB SATA2 - LiteOn LH-18A1P - Onboard Intel X3100 - TP-LINK PCI WiFi
3com Gigabit switch - Alcatel Speedtouch 585v6 - Forthnet ADSL Economy 24Mbps |
|
| Back to top |
|
 |
Kid The Xboxed

Gender:  Joined: 28 Sep 2006 Posts: 560 Location: really matters?
|
Posted: 02.06.2007, 17:31 Post subject: |
|
|
| psolid_snake wrote: | Sorry αλλά θα δημιουργηθεί buffer overflow από την gets() για να διαβάσει ένα string το πολύ μήκους 3 (yes or no) ?????????????????????????????????  |
Το θέμα δεν είναι εδώ Κώστα (αν και εδώ μπορεί να δημιουργηθεί πρόβλημα αν ο χρήστης θέλει), γενικά μιλάμε. _________________ dkalo.wordpress.com |
|
| Back to top |
|
 |
psolid_snake

Gender:  Joined: 09 Jan 2007 Posts: 211 Location: Kotsokalavryta
|
Posted: 02.06.2007, 17:56 Post subject: |
|
|
Ρε με κοροϊδεύετε.... σίγουρα η gets και όλο της το σόι δεν συμπεριφέρονται καλά αλλά ο κώδικας σου είναι αυτός!!!
Αν ήταν:
| Code: | printf("grapse thn istoria ths zwhs sou\n");
gets(istoria_ths_zwhs_mou); | φυσικά και δεν θα έβαζες gets()...
Από τη στιγμή όμως που το πρόβλημα σου είναι τόσο μα τόσο απλό δεν χρειάζεται να πνίγεσαι σε μια κουταλιά νερό!!!!
Φυσικά και ο χρήστης μπορεί να βάλει ότι θέλει και να σου κρεμάσει το πρόγραμμα (πάνω από 68 χαρακτήρες αν θυμάμαι καλά - με την fgets προλαμβάνεις αυτού) αλλά θα αυτή είναι και η επαφή σου με το χρήστη και η δέσμευση του να κάνει θεμιτές-επιτρεπτές διαδικασίες!!!!!!!!!  _________________ Και ας μην είμαστε γενναίοι... δεν υπάρχουν πιο ωραίοι!!! |
|
| Back to top |
|
 |
Kid The Xboxed

Gender:  Joined: 28 Sep 2006 Posts: 560 Location: really matters?
|
Posted: 02.06.2007, 18:17 Post subject: |
|
|
Το θέμα είναι ότι δεν υπάρχει λόγος να χρησιμοποιηθεί η gets() όταν η fgets() κάνει ακριβώς το ίδιο..  _________________ dkalo.wordpress.com |
|
| Back to top |
|
 |
|