saavedra29 Δημοσ. 18 Ιανουαρίου 2010 Δημοσ. 18 Ιανουαρίου 2010 παιδιά προσπαθώ να γράψω ένα πρόγραμμα στη C και έχω κολλήσει στο EOF. Δουλέυω σε linux και έχω δοκιμάσει -1, control-d....τίποτα. Ο κώδικας που δοκιμάζω είναι αυτός: >#include <stdio.h> int main() { int acou = 0 , bcou = 0 , ccou = 0 , dcou = 0 , fcou = 0; char grade ; printf ( "enter letter grade\n" ); printf ( "to end press the EOF\n" ); while ( grade != EOF ){ scanf ( "%s" , &grade ); if ( grade == 'a' ) acou++; else if ( grade == 'b' ) bcou++; else if ( grade == 'c' ) ccou++; else if ( grade == 'd' ) dcou++; else if ( grade == 'f' ) fcou++; else printf ( "enter a valuable grade\n" ); } printf ( "%d\n" , acou ); printf ( "%d\n" , bcou ); printf ( "%d\n" , ccou ); printf ( "%d\n" , dcou ); printf ( "%d\n" , fcou ); return 0; } Είναι ένα πρόγραμμα όπου σε προηγούμενο κώδικα έπρεπε να αντικαταστήσω τη switch με if else. Πιθανόν να έχω κάνει και άλλα λάθη μια και δεν έχω κατανοήσει τις διαφορές ανάμεσα σε strings, characters κλπ. π.χ. ίσως αντι για >char grade; έπρεπε να δηλώσω >int grade; και μετά αντί για >while ( grade != EOF ){ να γράψω >while ( (grade = getchar() ) != EOF ){ ; Δεν ξέρω ρε παιδιά τα έχω μπερδέψει τελείως. Αν μπορεί κάποιος να βοηθήσει έστω στο θέμα του EOF;
bxenos Δημοσ. 18 Ιανουαρίου 2010 Δημοσ. 18 Ιανουαρίου 2010 Ναι στο > int grade; do{ grade = getchar(); switch(grade){ case 'a': sjkhsdfjkghsdfjk break; } } while(grade != EOF); Αυτό είναι το σωστό. Στον κώδικα σου: Εσυ διαβάζεις σαν string(!!!!) ένα χαρακτηρα και δεν ελέγχεις για EOF. Ενημερωτικά δεν σκαει το πρόγραμμα γιατί το grade για λόγους τακτοποίησης μνημης πιάνει 4 bytes, οπότε παρόλο που εσυ δίνεις ένα χαρακτηρα, πέρνεις 2 (και το NUL). Δοκίμασε αν θέλεις να διαβάζεις string να ελέγξεις τι επιστρέφει η scanf ή όρισε εσυ ένα string που ο χρήστης να δίνει για τελος,
saavedra29 Δημοσ. 19 Ιανουαρίου 2010 Μέλος Δημοσ. 19 Ιανουαρίου 2010 ορίζω ένα string που ο χρήστης δίνει για τέλος: >while ( grade != 'z' ){ και το πρόγραμμα δουλέυει. Αλλά μου βγάζει στο τέλος > Segmentation fault
bxenos Δημοσ. 19 Ιανουαρίου 2010 Δημοσ. 19 Ιανουαρίου 2010 Ξαναδιάβασε αυτό Στον κώδικα σου:Εσυ διαβάζεις σαν string(!!!!) ένα χαρακτηρα και δεν ελέγχεις για EOF. Ενημερωτικά δεν σκαει το πρόγραμμα γιατί το grade για λόγους τακτοποίησης μνημης πιάνει 4 bytes' date=' οπότε παρόλο που εσυ δίνεις ένα χαρακτηρα, πέρνεις 2 (και το NUL).[/quote'] Εχεις δεσμέυσει buffer 1 χαρακτηρα. Πας να διαβάσεις λέξη με περισσότερους, αρα επικαλύπτεις μνήμη (segmentation fault)
npapak Δημοσ. 19 Ιανουαρίου 2010 Δημοσ. 19 Ιανουαρίου 2010 Βασικά έχεις ένα μικρο λάθος σε αυτά που γράφεις, το ότι δηλώνεις char και διαβάζεις string. Δεν είναι απόλυτα λάθος αυτό, αρκεί να δηλώσεις πίνακα απο chars. Τώρα για το EOF δεν ξέρω τι παίζει, αλλά γενικά είναι το CTRL+D. Εγώ έβαλα space στην θέση του EOF. > #include <stdio.h> int main() { int acou = 0 , bcou = 0 , ccou = 0 , dcou = 0 , fcou = 0; char grade ; printf ( "enter letter grade\n" ); printf ( "to end press the SPACE\n" ); while ( grade != ' ' ){ scanf ( "%c" , &grade ); if ( grade == 'a' ) acou++; else if ( grade == 'b' ) bcou++; else if ( grade == 'c' ) ccou++; else if ( grade == 'd' ) dcou++; else if ( grade == 'f' ) fcou++; else printf ( "enter a valuable grade\n" ); } printf ( "%d\n" , acou ); printf ( "%d\n" , bcou ); printf ( "%d\n" , ccou ); printf ( "%d\n" , dcou ); printf ( "%d\n" , fcou ); return 0; }
bxenos Δημοσ. 19 Ιανουαρίου 2010 Δημοσ. 19 Ιανουαρίου 2010 Οταν ξεφύγεις απο το EOF/segmentation fault και προλάβεις να δεις πίνακες, ρίξε μια ματιά και σ'αυτο > #include <stdio.h> #include <string.h> int main(){ int cou['f'-'a'+1],grade; //πινακας να χωρα νούμερα για a,b,c,d,e,f θεσεις memset(cou,0,sizeof(cou)); //μηδενισε τα περιεχομενα του πίνακα printf ( "enter letter grade\n" ); printf ( "to end press the EOF\n" ); while((grade=getchar())!=EOF) if(grade>='a' && grade<='f') //αν είναι στα επιθυμιτα grades cou[grade-'a']++; //μέτρα το στη θεση του στον πινακα for(grade='a';grade<='f';grade++) printf ( "grade %c = %d\n" , grade, cou[grade-'a'] ); return 0; }
bxenos Δημοσ. 19 Ιανουαρίου 2010 Δημοσ. 19 Ιανουαρίου 2010 βρε παιδια τα ' παμε αυτά. Το linux έχει ctrl-d και το dos/win ctrl-z. Οι τιμές τους είναι ctrl-d == 'D'-'@' και ctrl-z == 'Z'-'@'. Δεν χρειάζεται να ασχολούμαστε με αυτές τις τιμές. Η c μετατρέπει αυτούς τους χαρακτήρες (αν υπάρχουν - ΔΕΝ είναι υποχρεωτικό να υπάρχουν και συνήθως δεν υπάρχουν). Τους μετατρέπει σε EOF δηλαδή -1 για να μην σπάει τα απαυτα του ο προγραμματιστης.
saavedra29 Δημοσ. 20 Ιανουαρίου 2010 Μέλος Δημοσ. 20 Ιανουαρίου 2010 bxenos από αυτά που μου είπες κατάλαβα κάτι λίγα... Όταν τρέξω αυτό το πρόγραμμα: >#include <stdio.h> int main() { int acou = 0 , bcou = 0 , ccou = 0 , dcou = 0 , fcou = 0; char grade ; printf ( "enter letter grade\n" ); printf ( "to end press the EOF\n" ); while ( grade != 'z' ){ scanf ( "%c" , &grade ); if ( grade == 'a' ) acou++; else if ( grade == 'b' ) bcou++; else if ( grade == 'c' ) ccou++; else if ( grade == 'd' ) dcou++; else if ( grade == 'f' ) fcou++; else printf ( "enter a valuable grade\n" ); } printf ( "%d\n" , acou ); printf ( "%d\n" , bcou ); printf ( "%d\n" , ccou ); printf ( "%d\n" , dcou ); printf ( "%d\n" , fcou ); return 0; } μου δίνει: aris@saavedra29:~/Επιφάνεια εργασίας$ ./test2 enter letter grade to end press the EOF a enter a valuable grade a enter a valuable grade c enter a valuable grade v enter a valuable grade enter a valuable grade b enter a valuable grade b enter a valuable grade v enter a valuable grade enter a valuable grade v enter a valuable grade enter a valuable grade z enter a valuable grade 2 2 1 0 0 aris@saavedra29:~/Επιφάνεια εργασίας$ δηλαδή, όπως μου είχες πει, μου δίνει μία τιμή συν μια null. Πάει αυτό. Όταν αλλάξω το %c με %s δε μου δίνει τη null αλλά δείχνει segmantation fault. Μήπως γίνεται να μου δείξεις τί ακριβώς κώδικα πρέπει να γράψω; Γιατί αλλιώς δε βλέπω να το καταλαβαίνω. Υ.Γ. ωραίο το προγραμματάκι που παράθεσες πιό πάνω, αλλά το επόμενο κεφάλαιο που έχω να μάθω είναι οι συναρτήσεις και μετά οι πίνακες...έχω δρόμοοοο! ---------- Προσθήκη στις 20:01 ---------- Προηγούμενο μήνυμα στις 19:58 ---------- npapak αυτόν τον κώδικα τον τρέχω και μου δίνει δύο τιμές εξόδου, μία κανονική και μία null, όπως μου έγραψε και ο bxenos επάνω.
bxenos Δημοσ. 20 Ιανουαρίου 2010 Δημοσ. 20 Ιανουαρίου 2010 > #include <stdio.h> int main() { int acou = 0 , bcou = 0 , ccou = 0 , dcou = 0 , fcou = 0; char grade ; printf ( "enter letter grade\n" ); printf ( "to end press the EOF\n" ); while ( grade != 'z' ){ scanf ( "%c" , &grade ); [color="Red"] if(grade == '\n') ; else [/color] if ( grade == 'a' ) acou++; else if ( grade == 'b' ) bcou++; else if ( grade == 'c' ) ccou++; else if ( grade == 'd' ) dcou++; else if ( grade == 'f' ) fcou++; else printf ( "enter a valuable grade\n" ); } printf ( "%d\n" , acou ); printf ( "%d\n" , bcou ); printf ( "%d\n" , ccou ); printf ( "%d\n" , dcou ); printf ( "%d\n" , fcou ); return 0; } Οταν χρησιμοποιείς "%c" στο scanf, διαβάζει ότι χαρακτηρες πληκτρολογείς. Τι πληκτρολογείς; Ενα γράμμα και ΕΝΤΕΡ. Αυτο σου δίνει: ένα γραμμα (π.χ. 'a') και ENTRER ('\n') Με την προσθηκη με τα κοκκινα, αγνοεις τα '\n' και δεν εκτελειται το else που τυπωνει μηνυμα λαθους. Αν έβαζες "%s", τοτε το scanf θα διάβαζε το γραμμα και θα κόλαγε και ένα NUL απο πίσω του, δηλαδή 2 χαρακτηρες. Εσυ όμως εχεις δηλωσει το grade ως char (1 χαρακτηρας). Αρα γράφεις 2 χαρακτηρες σε 1 χαρακτηρα (αρα παραβιαζεις τη μνημη - segmentation fault). Να και λυση με "%s" > #include <stdio.h> int main() { int acou = 0 , bcou = 0 , ccou = 0 , dcou = 0 , fcou = 0; char grade[2] ; printf ( "enter letter grade\n" ); printf ( "to end press the EOF\n" ); while ( grade[0] != 'z' ){ scanf ( "%s" , grade ); if ( grade[0] == 'a' ) acou++; else if ( grade[0] == 'b' ) bcou++; else if ( grade[0] == 'c' ) ccou++; else if ( grade[0] == 'd' ) dcou++; else if ( grade[0] == 'f' ) fcou++; else printf ( "enter a valuable grade\n" ); } printf ( "%d\n" , acou ); printf ( "%d\n" , bcou ); printf ( "%d\n" , ccou ); printf ( "%d\n" , dcou ); printf ( "%d\n" , fcou ); return 0; } Αλλα το "%s" σημαινει ΠΙΝΑΚΕΣ! Δεν υπαρχει κανονικα "%s" χωρις πίνακες. (υπαρχουν μαϊμουδιες που μπορούν να γίνουν χωρις πίνακες αλλά ο κωδικας δεν θα είναι standard και portable). Αυτό που δεν καταλαβαίνω είναι γιατι επιμένεις στο scanf. Θα προτιμούσα έτσι τη λύση: > #include <stdio.h> int main() { int acou = 0 , bcou = 0 , ccou = 0 , dcou = 0 , fcou = 0; [color="Red"] int grade = '\n';[/color] printf ( "enter letter grade\n" ); printf ( "to end press the EOF\n" ); while ( grade != EOF){ [color="Red"] if(grade == '\n') ; else [/color] if ( grade == 'a' ) acou++; else if ( grade == 'b' ) bcou++; else if ( grade == 'c' ) ccou++; else if ( grade == 'd' ) dcou++; else if ( grade == 'f' ) fcou++; else printf ( "enter a valuable grade\n" ); [color="#ff0000"] grade = getchar(); [/color] } printf ( "%d\n" , acou ); printf ( "%d\n" , bcou ); printf ( "%d\n" , ccou ); printf ( "%d\n" , dcou ); printf ( "%d\n" , fcou ); return 0; }
saavedra29 Δημοσ. 20 Ιανουαρίου 2010 Μέλος Δημοσ. 20 Ιανουαρίου 2010 καλά, bxenos μου πήρε μια ώρα για να συνειδητοποιήσω ότι ακόμα και όταν πατάω enter (σε τύπο %C) εισάγω χαρακτήρα!!! Τώρα κατάλαβα γιατί μου έβγαζε 2 τιμές. Ο τρίτος κώδικας που μου έδωσες με κούφανε, δεν ήξερα πως μπορώ να εισάγω τιμή χωρίς scanf! Δυστυχώς το "C προγραμματισμός" με πάει κάπως γρήγορα.Μάλλον έπρεπε να πάρω ένα βιβλίο για τελείως αρχάριους.Αναφέρεται στους χαρακτήρες στο όγδοο κεφάλαιο ενώ μου ζητάει να γράψω τέτοια προγράμματα ήδη από το τέταρτο Παιδιά σας ευχαριστώ πολύ για τη βοήθεια!
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.