Remalia
Official forum of Remalia (Ntk & Friends)


 

 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

fgets(), while loops & problems..



 
Post new topic   Reply to topic    Remalia Forum Index -> Προγραμματισμός σε C/C++, Java, Fortran etc.
View previous topic :: View next topic  
Author Message
Kid
The Xboxed



Gender: Gender:Male
Joined: 28 Sep 2006
Posts: 560
Location: really matters?

PostPosted: 01.06.2007, 20:22    Post subject: fgets(), while loops & problems.. Reply with quote

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 επαναλαμβάνεται χωρίς να σταματάει. Καμιά ιδέα για το τι φταίει? Mit den Augen rollen
_________________
dkalo.wordpress.com
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Advertisment








PostPosted: 01.06.2007, 20:22    Post subject: Advertisment

Back to top
Thinker_




Gender: Gender:Male
Joined: 11 Oct 2006
Posts: 104
Location: Here & there

PostPosted: 02.06.2007, 13:37    Post subject: Reply with quote

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)
Code:
c = getchar();

μέσα στο loop, και ο έλεγχος θα είναι:
Code:
c == 'n'


Αν δεν απατώμαι δε, ότι και να σου δώσει ο χρήστης, η getchar θα κρατήσει μόνο τον πρώτο χαρακτήρα, οπότε αν θες μπορείς να προσθέσεις έναν extra έλεγχο και να ξαναζητάς είσοδο σε περίπτωση χαρακτήρα διαφορου των y,n.

PS: Τι πρόγραμμα είναι αυτό;
_________________
Catchy-smart signature goes here. Just pretend to laugh, and we're done.
Back to top
View user's profile Send private message Send e-mail MSN Messenger
Kid
The Xboxed



Gender: Gender:Male
Joined: 28 Sep 2006
Posts: 560
Location: really matters?

PostPosted: 02.06.2007, 14:23    Post subject: Reply with quote

Το έχει αδειάσει το stdin αφού προηγουμένως έχω κάνει fflush(stdin).

Δεν θέλω y/n, προτιμώ "ολοκληρωμένες" λύσεις (επί της ουσίας καμία διαφορά βέβαια).

Πρόβλημα στην δήλωση των μεταβλητών δεν υπάρχει επειδή μετά την προσθήκη του fflush(stdin) εκτελείται το loop αλλά εκτελείται 1 φορά χωρίς να δουλέψει το fgets() & την δεύτερη φορά περιμένει για input.

Η αντικατάσταση που προτείνεις δεν αλλάζει κάτι αφού το size του πίνακα, είναι ορισμένο εξαρχής και δεν δημιουργείται με malloc().

Encrypter φτιάχνω Γιώργο.
_________________
dkalo.wordpress.com
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
parsifal
Florumator



Gender: Gender:Male
Joined: 02 Oct 2006
Posts: 626
Location: Woodstock '69

PostPosted: 02.06.2007, 14:54    Post subject: Reply with quote

Σε ποιο σημείο βάζεις την 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
View user's profile Send private message MSN Messenger
Thinker_




Gender: Gender:Male
Joined: 11 Oct 2006
Posts: 104
Location: Here & there

PostPosted: 02.06.2007, 14:58    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail MSN Messenger
psolid_snake




Gender: Gender:Male
Joined: 09 Jan 2007
Posts: 211
Location: Kotsokalavryta

PostPosted: 02.06.2007, 14:59    Post subject: Reply with quote

Δεν υπάρχει λόγος αφού χρησιμοποιείς ως βασικό input το πληκτρολόγιο να κάνεις fgets... Μόνο και μόνο η gets σου αρκεί!! Όπως σου είπα και χθες το προβλημα σου είναι στο έλεγχο της while!!!
Δοκίμασε μόνο με gets και όλα θα πρέπει να είναι εντάξει!!! Αν τρέξεις μόνο το συγκεκριμένο κομμάτι του κώδικα σου το πρόβλημα εντοπίζεται στην strcmp αν και η fgets έχει κάνει σωστά την δουλειά της πιο πάνω και έχει αποθηκεύσει το σωστό (yes or no) που έχει εισάγει ο χρήστης!!!
Τουλάχιστον στον κώδικα που σου έστειλα χθες όλα λειτουργούσαν σωστά με την χρήση μόνο της gets...

Άσε τους encrypter και πιάσε το MINIX ρεεεεεεεεεεε........ Auf den Arm nehmen Auf den Arm nehmen Mit den Augen rollen
_________________
Και ας μην είμαστε γενναίοι... δεν υπάρχουν πιο ωραίοι!!!
Back to top
View user's profile Send private message Send e-mail MSN Messenger
parsifal
Florumator



Gender: Gender:Male
Joined: 02 Oct 2006
Posts: 626
Location: Woodstock '69

PostPosted: 02.06.2007, 15:03    Post subject: Reply with quote

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
View user's profile Send private message MSN Messenger
Kid
The Xboxed



Gender: Gender:Male
Joined: 28 Sep 2006
Posts: 560
Location: really matters?

PostPosted: 02.06.2007, 16:47    Post subject: Reply with quote

Η gets() δημιουργεί buffer overflow εφόσον δεν ορίζεται το μέγιστο μήκος του string που θα διαβαστεί όπως πολύ σωστά είπε ο Αλέκος.

Γιώργο δεν γίνεται πλήρης αντικατάσταση της scanf() από την fgets() και αντίστροφα. Αναγκαστικά θα χρησιμοποιήσεις και τις 2. Αντίστοιχα ισχύει το ίδιο και για τις εντολές εκτύπωσης.
_________________
dkalo.wordpress.com
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
psolid_snake




Gender: Gender:Male
Joined: 09 Jan 2007
Posts: 211
Location: Kotsokalavryta

PostPosted: 02.06.2007, 17:23    Post subject: Reply with quote

Sorry αλλά θα δημιουργηθεί buffer overflow από την gets() για να διαβάσει ένα string το πολύ μήκους 3 (yes or no) ????????????????????????????????? Geschockt Geschockt Geschockt Geschockt Geschockt
_________________
Και ας μην είμαστε γενναίοι... δεν υπάρχουν πιο ωραίοι!!!
Back to top
View user's profile Send private message Send e-mail MSN Messenger
parsifal
Florumator



Gender: Gender:Male
Joined: 02 Oct 2006
Posts: 626
Location: Woodstock '69

PostPosted: 02.06.2007, 17:30    Post subject: Reply with quote

psolid_snake wrote:
Sorry αλλά θα δημιουργηθεί buffer overflow από την gets() για να διαβάσει ένα string το πολύ μήκους 3 (yes or no) ????????????????????????????????? Geschockt Geschockt Geschockt Geschockt Geschockt


Στο συγκεκριμένο παράδειγμα, και αν υποθέσουμε ότι το εκτελέσιμο θα το χρησιμοποιεί μόνο ο 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
View user's profile Send private message MSN Messenger
Kid
The Xboxed



Gender: Gender:Male
Joined: 28 Sep 2006
Posts: 560
Location: really matters?

PostPosted: 02.06.2007, 17:31    Post subject: Reply with quote

psolid_snake wrote:
Sorry αλλά θα δημιουργηθεί buffer overflow από την gets() για να διαβάσει ένα string το πολύ μήκους 3 (yes or no) ????????????????????????????????? Geschockt Geschockt Geschockt Geschockt Geschockt

Το θέμα δεν είναι εδώ Κώστα (αν και εδώ μπορεί να δημιουργηθεί πρόβλημα αν ο χρήστης θέλει), γενικά μιλάμε.
_________________
dkalo.wordpress.com
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
psolid_snake




Gender: Gender:Male
Joined: 09 Jan 2007
Posts: 211
Location: Kotsokalavryta

PostPosted: 02.06.2007, 17:56    Post subject: Reply with quote

Ρε με κοροϊδεύετε.... σίγουρα η gets και όλο της το σόι δεν συμπεριφέρονται καλά αλλά ο κώδικας σου είναι αυτός!!!
Αν ήταν:
Code:
printf("grapse thn istoria ths zwhs sou\n");
gets(istoria_ths_zwhs_mou);
φυσικά και δεν θα έβαζες gets()...
Από τη στιγμή όμως που το πρόβλημα σου είναι τόσο μα τόσο απλό δεν χρειάζεται να πνίγεσαι σε μια κουταλιά νερό!!!!
Φυσικά και ο χρήστης μπορεί να βάλει ότι θέλει και να σου κρεμάσει το πρόγραμμα (πάνω από 68 χαρακτήρες αν θυμάμαι καλά - με την fgets προλαμβάνεις αυτού) αλλά θα αυτή είναι και η επαφή σου με το χρήστη και η δέσμευση του να κάνει θεμιτές-επιτρεπτές διαδικασίες!!!!!!!!! Smilie Smilie
_________________
Και ας μην είμαστε γενναίοι... δεν υπάρχουν πιο ωραίοι!!!
Back to top
View user's profile Send private message Send e-mail MSN Messenger
Kid
The Xboxed



Gender: Gender:Male
Joined: 28 Sep 2006
Posts: 560
Location: really matters?

PostPosted: 02.06.2007, 18:17    Post subject: Reply with quote

Το θέμα είναι ότι δεν υπάρχει λόγος να χρησιμοποιηθεί η gets() όταν η fgets() κάνει ακριβώς το ίδιο.. Winken
_________________
dkalo.wordpress.com
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Display posts from previous:   
Post new topic   Reply to topic    Remalia Forum Index -> Προγραμματισμός σε C/C++, Java, Fortran etc. All times are GMT + 2 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

Similar Topics
Topic Author Forum Replies Posted
No new posts Forum problems.. Ntk Help & Support 11 03.10.2006, 21:04



Powered by phpBB 2.0.23 © 2001, 2002 phpBB Group


Thema 899201-899240 | Thema 295921-295960 | Thema 177881-177920

Impressum | Datenschutz

Bei iphpbb.com bekommen Sie ein Kostenloses Forum mit vielen tollen Extras