Εργαστήριο Τεχνολογίας Λογισμικού
+1 vote
557 views

gets(a);
for(i=0; a[i]!='\0''i++);
if(a[0]=='\n')
printf("%s", "empty");
για ποιον λογο δεν μο τυπωνει ποτε το empty οταν ο πρωτος χαρακτηρας ειναι enter;

in progintro by (250 points)
edited by | 557 views
+4

Γιατί δεν βάζεις έναν σωστό τίτλο στην ερώτηση σου ;

2 Answers

+4 votes

Αρχικά καλό είναι να βάζεις τίτλο στην ερώτηση σου ώστε εάν τύχει και έχουν και άλλοι την ίδια απορία με σένα να μπορούν να βρουν γρήγορα την απάντηση που ψάχνουν.

Πάμε τώρα στην ερώτηση. Πριν απαντήσω θα σου πω ότι υπάρχει ένα χρήσιμο εργαλείο εκεί έξω που λέγεται man page(manual page). Aυτός είναι ένας οδηγός για πολλές συναρτήσεις εκεί έξω που θα χρειαστεί να χρησιμοποιήσεις. Μία από αυτές είναι η

gets()

Μπορείς να δεις το man page της gets εδώ: gets' man page

Αυτό αναφέρει το εξής:

gets()  reads  a  line from stdin into the buffer pointed to by s until either a terminating newline or EOF, which it replaces with a null byte ('\0').  No check for buffer overrun is performed (see BUGS below).

Που σημαίνει ότι όταν στέλνεις χαρακτήρα αλλαγής γραμμής (δηλαδή όταν πατάς enter στο πληκτρολόγιο σου) η gets το αναγνωρίζει ως το τέλος της συμβολοσειράς και το αντικαθιστά με το '\0'. Επομένως δεν μπαίνει ποτέ στο if(a[0] == '\n') γι' αυτό και δεν τυπώνεται ποτέ το empty. Καλό θα ήταν να χρησιμοποιήσεις ένα while loop που θα διαβάζει έναν - έναν τους χαρακτήρες εισόδου μέσω της συνάρτησης getchar() και έτσι θα έχεις τον πλήρη έλεγχο εσύ.

Τέλος, η gets() δεν είναι καλή συνάρτηση, αν από περιέργεια πας και λίγο παρακάτω στο man page θα δεις αυτό:

it is  extremely dangerous to use. It has been used to break computer security.

Προς το παρών δε χρειάζεται να ξέρεις περισσότερα γι' αυτό. Αλλά να το θυμάσαι. :)) Καλή συνέχεια.

by (470 points)
+3 votes
  • Η συνάρτηση gets ειναι deprecated (κατά μία έννοια, σταμάτησαν να την υποστηρίζουν στις τελευταίες εκδόσεις C και C++), οπότε θα συνιστούσα να ακολουθήσεις κάποια άλλη εναλλακτική ( πχ fgets ).

  • Αν και δεν το αναφέρεις, μπορώ να μαντέψω πως το πρόγραμμά σου όχι μόνο δεν τυπώνει "empty", αλλά δεν τερματίζει κι'όλας. Αυτό γιατί οι πιο γνωστές τουλάχιστον συναρτήσεις που διαβάζουν συμβολοσειρά από την είσοδο δεν δέχονται ένα σκέτο '\n'.

  • Αν διαβάσεις από την είσοδο 12345\n αυτό που θα μπεί στη συμβολοσειρά είναι το 12345\0 (τουλάχιστον στις συμβολοσειρές C). Τα newline (\n) δεν εμφανίζονται συνήθως μέσα στους χαρακτήρες των συμβολοσειρών που διαβάζεις, γι'αυτό και οι συναρτήσεις τα αγνοούν, ή τα χρησιμοποιούν για να καταλάβουν πως η ανάγνωση τελείωσε (αφού πρώτα έχουν διαβάσει κάποια έγκυρη συμβολοσειρά -- η δικιά σου περίπτωση).

by (3.0k points)
edited by
0

Η gets διαβάζει μια χαρά το '\n' και συνεχίζει. Απλά το αντικαθιστά με '\0' όπως λες κι εσύ.
Υπάρχουν άλλες συναρτήσεις (όχι η gets) που έχουν αυτή τη συμπεριφορά που περιγράφεις στο δεύτερο bullet, δηλαδή να αγνοούν το whitespace (πχ scanf).

+1

Αν το κάνει αυτό η gets δεν το γνώριζα :) (υποθέτω αναφέρεσαι στην εισαγωγή σκέτου \n χωρίς κάποιο κείμενο πιο πρίν)
Γι'αυτό πρόσθεσα και το "οι πιο γνωστές τουλάχιστον"

Πάντως όσον αφορά το deprecation θυμάμαι την gets να μου σπάει το κεφάλι με το undefined behavior, οπότε όσο μπορείτε μακριά :D

0

Ναι συγγνώμη δεν το εξέφρασα καλά. Αυτό που ήθελα να πω απλώς είναι ότι θα τερματίσει με την gets. Κατά τα άλλα μια χαρά το έθεσες.

301 questions

289 answers

288 comments

899 users