Star_Light Δημοσ. 11 Αυγούστου 2012 Δημοσ. 11 Αυγούστου 2012 πριν ήταν όμως (πινακας με χαρακτήρες) Ε ναι αλλα τον έβγαλα γιατι μου δειξε το κολπο ο ημιθεος. Αλλα και παλι αμα βάζαμε έναν '\0' στο τελευταιο στοιχειο πες του πινακα ας πουμε στο [25] τοτε το 'Z' ή 'z' που θα εμπαινε? Τα strings ειναι πινακες απο χαρακτηρες ... αλλα σε υποχρεωνει κανεις να χρησιμοποιησεις εναν char πινακα και να ειναι εγκυρο C- string? με τον μηδενικο χαρακτηρα στο τελος. Kανονικα η getchar παιρνει εναν χαρακτηρα την φορα απλα στα loops τους παιρνει ολους μαζι μεχρι να πατησεις ΕΝΤΕΡ και τους αποθηκευει στο buffer. Για αυτο εχεις την εντυπωση οτι και καλα επεξεργαζεται προτασεις... αμα δεν υπηρχε το loop δεν θα μπορουσαμε να το κανουμε αυτο.
migf1 Δημοσ. 11 Αυγούστου 2012 Δημοσ. 11 Αυγούστου 2012 http://www.insomnia....c/page__st__210 εδω έχεις κανει ένα λαθος στην συμβολοσειρα. Θα επρεπε να πω οτι ο κωδικας σου ειναι κακος και να αρχισω την αυστηρη κριτικη? Και οτι αμα πας σε επιχειρηση θα πρεπει να φυγεις αεροπορικως???? απο το παραθυρο. Επειδη λετε εμενα εριστικο μετα. Ανθρωπος εισαι φιλε. Δεν εισαι μηχανη. Αλλα και μηχανη να ησουν το σφαλμα θα ηταν σιγουρο. Εξηγησα οτι η τοπικη μεταβλητη χαρακτηρα μεσα στην συναρτηση ηταν λαθος ασυναισθητο. Ολα αυτα που χεις αριθμησει εχουν διορθωθει πολυ πριν το μηνυμα μου στο οποιο έκανες παράθεση..... Διαβαζοντας το νήμα, βλέπω πως σου έδωσα κώδικα που έλυνε όλα τα προβλήματα που είχε ο δικός σου, έκανε και παραπάνω πράγματα, αλλά εισήγαγε ένα bug με το κενό. Το βρήκες και το διόρθωσες. Πάρε τους 2 κώδικες (τον αρχικο δικό σου, με τον αρχικό δικό μου), δώσε τους σε έναν interviewer και ρωτα τον ποιον από τους 2 θα προσελάμβανε. Ο King έχει αφιερωσει καμποσα χρονια για να πάρει πτυχια απο το Berkeley κτλπ... ειναι λιγακι αστειο να συγκριθουμε. Εγω μονος μου μαθαινω κ τελειωσα απλα και μια σχολη οπως ολος ο κοσμος. Εσύ όμως ανεφερες τον Κινγκ στη συζήτηση για να δικαιολογήσεις ότι χρησιμοποιεις globals, δεν τον ανέφερα εγώ... εγώ απλά απάντησα σε αυτή σου την αναφορά. Δεν θεωρησα στις συναρτησεις ποτε αυτο που λες δομικα ισοδυναμο. Αλλα ποιος θα σου ελεγε το οτιδηποτε αμα το εβαζες μεσα σε μια συναρτηση fill_and_rev και εκανε μια χαρα τη δουλεια του ? Αν έχεις κατι σαν αυτο > //Εκτυπωση μιας προτασης χωρις τα κενα της.... #include <stdio.h> int main(void) { char ch , array[100]={'\0'}; int i=0 , count=0; printf("Enter a sentence: "); while((ch=getchar())!='.' && ch != '?' && ch != '!' && i<100 ) array[i++]=ch; for(count=0; count<i; count++) { if(array[count] == ' ') continue; else printf("%c" , array[count]); } putchar(ch); return 0; } Αυτο αν θελησεις να το παρεις σαν module και να το χρησιμοποιησεις σε εναν αλλο κωδικα σαν συναρτηση ωστε να μην διπλογραφεις ξανα κωδικα που θα θες να κανει αυτη τη δουλεια ετσι οπως το χω γραμμενο..... θα χρειαστει να το κανω συναρτηση. Με οτι αυτο συνεπαγεται..... ενω αν ηταν ετοιμο πραγμα που δεν ειναι στην δικη σου main() δεν θα ειχες τετοιο θεμα. Τωρα εσυ τι θα κανεις? θα ξαναγραψεις τον κωδικα αν χρειαστεις τον ιδιο σε αλλο προγραμμα? Στον δικο σου κωδικα... αν υποθεσουμε οτι αυτο εδω θα το χρησιμοποιησεις : > for (cp=input, len=0, nValid=0; *cp; cp++,len++) { if ( isalpha(*cp) ) { lettcount[ tolower(*cp) - 'a' ]++; nValid++; } } Θα πρεπει να το κανεις συναρτηση..... δηλαδη εξτρα δουλεια ενω αν το ειχες φτιαξει εξαρχης και δεν ηταν ολα μεσα στην main() δεν θα ειχες αυτο το εξτρα μετα.... οι συναρτησεις ειναι για να μην διπλογραφουμε κωδικα ετσι δεν ειναι? ΜΙας και το παμε αυστηρα δηλαδη... να τα δουμε ολα. Εστω και την τριχια Σε συνάρτηση βάζουμε συνηθως όποιον κώδικα θέλουμε να επαναχρησιμοποιήσουμε ατόφιο. Στην άσκησή σου δεν επαναχρηισμοποιείς τίποτα, οπότε δεν χρειάζεσαι καν συναρτησεις. Δεν θα σου πει κανεις τίποτα αν χρησιμοποιήεις συναρτήσεις, αλλά σε καμία περίτωση δεν δικαιούσαι να χαρακτηρίσεις κακό κώδικα αυτόν που δεν χρησιμοποιεί συναρτήσεις στην υλοποίηση της συγκεκριμενης άσκησης. Εϊναι μάλιστα το αυτονόητο να μην έχει συναρτήσεις μια τετοια άσκηση (και όχι το ανάποδο). Υ.Γ1 Οταν λες οτι θα πρεπει η στοιχιση να ειναι ομοιογενης εννοεις οτι θα πρεπει να χρησιμοποιώ το Tab οταν γραφω κώδικα ? Εννοώ πχ πως κλέινεις άγκιστρα σε διαφορετικές εσοχές από το αντίστοιχα άγκιστρα ανοίγματος. Ή πως π.χ. έχεις άλλη εσοχή για την main() κι άλλη για τις υπολοιπες συναρτήσεις. Υ.Γ2 Οταν λες υπογραφη εννοεις την κεφαλιδα της συνάρτησης? Δωσε εσυ ενα αντιπροσωπευτικο ονομα να δουμε. Το process_input για μενα ειναι ενταξει παντως. Αυτό το διόρθωσες μετά την εππισήμανσή μου. Η επισήμανσή μου αφορούσε την read( ch ).
Star_Light Δημοσ. 11 Αυγούστου 2012 Δημοσ. 11 Αυγούστου 2012 Διαβαζοντας το νήμα, βλέπω πως σου έδωσα κώδικα που έλυνε όλα τα προβλήματα που είχε ο δικός σου, έκανε και παραπάνω πράγματα, αλλά εισήγαγε ένα bug με το κενό. Το βρήκες και το διόρθωσες. Πάρε τους 2 κώδικες (τον αρχικο δικό σου, με τον αρχικό δικό μου), δώσε τους σε έναν interviewer και ρωτα τον ποιον από τους 2 θα προσελάμβανε. Κοιταξε να δεις επειδη σεβομαι καποια πραγματα δεν θα συνεχισω τον αντιλογο. Εκτος αυτου δεν πειθεται καποιος με επιχειρηματα. Δεν ξεχναω τα λεγομενα μου. Απλα να χεις υποψιν σου οτι ποτε δεν έχεις πει έναν καλο λογο οταν επρεπε περα απο την αυστηρη κριτικη που κανεις.
imitheos Δημοσ. 11 Αυγούστου 2012 Δημοσ. 11 Αυγούστου 2012 Τα strings ειναι πινακες απο χαρακτηρες ... αλλα σε υποχρεωνει κανεις να χρησιμοποιησεις εναν char πινακα και να ειναι εγκυρο C- string? με τον μηδενικο χαρακτηρα στο τελος. Οι πρότυπες συναρτήσεις που υπάρχουν στις libc δουλεύουν με "C Strings" δηλαδή πίνακες από χαρακτήρες με σημείο τέλους το '\0'. Αν θέλεις μπορείς να μη χρησιμοποιείς αυτή τη σύμβαση απλά μετά δεν θα μπορείς να χρησιμοποιείς αυτές τις συναρτήσεις (πχ η printf("%s", tade) δεν θα παίζει). Kανονικα η getchar παιρνει εναν χαρακτηρα την φορα απλα στα loops τους παιρνει ολους μαζι μεχρι να πατησεις ΕΝΤΕΡ και τους αποθηκευει στο buffer. Για αυτο εχεις την εντυπωση οτι και καλα επεξεργαζεται προτασεις... αμα δεν υπηρχε το loop δεν θα μπορουσαμε να το κανουμε αυτο. Πρακτικά έτσι γίνεται αλλά η διατύπωση σου δεν είναι απόλυτα σωστή. Η getchar δέχεται και επιστρέφει ένα χαρακτήρα. Αυτή είναι η λειτουργία της και αυτό κάνει πάντα. Και μία φορά να την τρέξεις πάλι θα περιμένει να πατήσεις enter. Δεν το κάνει αυτό επειδή την έχεις μέσα σε loop και άσε που δεν μπορεί να γνωρίζει η getchar ότι την τρέχεις σε loop. Αυτό που γίνεται είναι ότι το πρόγραμμα που οδηγεί το "τερματικό" σου δουλεύει από τη μάνα του με γραμμές (line buffered) και η getchar "βλέπει" αυτό που έχεις δώσει μόνο αφού πατηθεί το enter. Για να γίνει πιο κατανοητό αυτό που λέω, σκέψου ότι γράφεις σε ένα τερματικό σε *nix ή στη "γραμμή εντολών ms-dos" στα windows. Η εντολή τρέχει μόνο αφού πατήσεις enter και μέχρι να το πατήσεις μπορεί να έχεις πληκτρολογήσει 100 χαρακτήρες και να έχεις σβήσει τους 90 με το backspace. Η getchar σου θα δει μόνο τους 10 που απέμειναν.
Star_Light Δημοσ. 11 Αυγούστου 2012 Δημοσ. 11 Αυγούστου 2012 Οι πρότυπες συναρτήσεις που υπάρχουν στις libc δουλεύουν με "C Strings" δηλαδή πίνακες από χαρακτήρες με σημείο τέλους το '\0'. Αν θέλεις μπορείς να μη χρησιμοποιείς αυτή τη σύμβαση απλά μετά δεν θα μπορείς να χρησιμοποιείς αυτές τις συναρτήσεις (πχ η printf("%s", tade) δεν θα παίζει). Ακριβως !!! Το ειχα στο μυαλο μου οτι μετα δεν θα μπορεσεις να εκτυπωσεις κατι σαν string... ουτε με την puts γιατι λογικα δεν θα βρισκει τον κενο. Πρακτικά έτσι γίνεται αλλά η διατύπωση σου δεν είναι απόλυτα σωστή. Η getchar δέχεται και επιστρέφει ένα χαρακτήρα. Αυτή είναι η λειτουργία της και αυτό κάνει πάντα. Και μία φορά να την τρέξεις πάλι θα περιμένει να πατήσεις enter. Δεν το κάνει αυτό επειδή την έχεις μέσα σε loop και άσε που δεν μπορεί να γνωρίζει η getchar ότι την τρέχεις σε loop. Αυτό που γίνεται είναι ότι το πρόγραμμα που οδηγεί το "τερματικό" σου δουλεύει από τη μάνα του με γραμμές (line buffered) και η getchar "βλέπει" αυτό που έχεις δώσει μόνο αφού πατηθεί το enter. Για να γίνει πιο κατανοητό αυτό που λέω, σκέψου ότι γράφεις σε ένα τερματικό σε *nix ή στη "γραμμή εντολών ms-dos" στα windows. Η εντολή τρέχει μόνο αφού πατήσεις enter και μέχρι να το πατήσεις μπορεί να έχεις πληκτρολογήσει 100 χαρακτήρες και να έχεις σβήσει τους 90 με το backspace. Η getchar σου θα δει μόνο τους 10 που απέμειναν. Εγω εννοουσα οτι αμα δεν υπηρχε το loop που σταματαει στο ENTER (αμα του πεις να σταματαει εκει) δεν θα μπορουσες να επεξεργαστεις ολους τους χαρακτηρες μαζι. Αυτο συμβαινει επειδη η getchar καλειται πολλες φορες και παιρνει καθε φορα εναν χαρακτηρα.
imitheos Δημοσ. 11 Αυγούστου 2012 Δημοσ. 11 Αυγούστου 2012 > #include <stdio.h> #include <stdlib.h> #include <termios.h> int main(void) { struct termios told, tnew; int ch; tcgetattr(0, &told); tnew = told; tnew.c_lflag &= ~ICANON; tcsetattr(0, TCSANOW, &tnew); while ((ch = getchar()) != 'q') { if (ch == '\n') printf("Pliktrologises Enter\n"); else if (ch == 127) printf("Pliktrologises Backspace\n"); else printf("Pliktrologises %c(%d)\n", ch, ch); } tcsetattr(0, TCSANOW, &told); return 0; } Αν χρησιμοποιείς κάποιο linux, *bsd, κτλ δοκίμασε το παραπάνω πρόγραμμα και θα δεις ότι η getchar θα επιστρέφει σε κάθε χαρακτήρα καθώς και ότι θα επιστρέφει χύμα τα Enter και Backspace χωρίς να ρυθμίζεται η λειτουργία τους από το τερματικό.
Star_Light Δημοσ. 11 Αυγούστου 2012 Δημοσ. 11 Αυγούστου 2012 Nαι λογω line - buffering θα ειναι ρυθμισμενο ωστε να μην ξεκιναει η επεξεργασια οταν πατηθει το ENTER. Uploaded with ImageShack.us Στην Σελ. 314 λεει πως η συναρτηση ειναι ενταμιευμενη.... περα απο το οτι η συναρτηση δεχεται εναν χαρακτηρα καθε φορα που καλειται... το λειτουργικο συστημα λεει εδω φερει ολους τους χαρακτηρες στο buffer μεχρι να πατησεις ENTER κ κατοπιν τους στελνει στην stdin. Tελοςπαντων ειχε γινει συζητηση για αυτο παλιοτερα. Νομιζω πανω κατω λεμε το ιδιο πραγμα. Ετσι οπως το γραφει παντως εδω το βιβλιο το ριχνει στην συναρτηση και οχι στις ρυθμισεις του κελυφους.
imitheos Δημοσ. 11 Αυγούστου 2012 Δημοσ. 11 Αυγούστου 2012 Ετσι οπως το γραφει παντως εδω το βιβλιο το ριχνει στην συναρτηση και οχι στις ρυθμισεις του κελυφους. Και εγώ δεν ανέφερα ρυθμίσεις κελύφους αλλά Terminal Driver. Στην Σελ. 314 λεει πως η συναρτηση ειναι ενταμιευμενη.... περα απο το οτι η συναρτηση δεχεται εναν χαρακτηρα καθε φορα που καλειται... το λειτουργικο συστημα λεει εδω φερει ολους τους χαρακτηρες στο buffer μεχρι να πατησεις ENTER κ κατοπιν τους στελνει στην stdin. Ποιος είναι ο αγγλικός όρος για το Ενταμιευμένη γιατί δεν κατάλαβα τι εννοεί ? "Είμαστε very very χολοσκασμένες" που λέει και η θεία απ το σικάγο Γεωργία Βασιλειάδου
Star_Light Δημοσ. 11 Αυγούστου 2012 Δημοσ. 11 Αυγούστου 2012 Και εγώ δεν ανέφερα ρυθμίσεις κελύφους αλλά Terminal Driver. Ποιος είναι ο αγγλικός όρος για το Ενταμιευμένη γιατί δεν κατάλαβα τι εννοεί ? "Είμαστε very very χολοσκασμένες" που λέει και η θεία απ το σικάγο Γεωργία Βασιλειάδου hahahahha δεν εχω ιδεα ! Δεν το εχω δει στα αγγλικα δυστυχως. Αμα το βρεις σφύρα και απο εδω τπτ...
defacer Δημοσ. 12 Αυγούστου 2012 Δημοσ. 12 Αυγούστου 2012 > #include<stdio.h> #include<stdlib.h> #include<string.h> int main(int argc,char *argv[]) { int i=0; char f[][80]={"add","substract","multiply","divide",""}; int k=atoi(argv[2]); int j=atoi(argv[3]); if(!strcmp(f[0],argv[1]))printf("The sum is:%d\n",k+j); else if(!strcmp(f[1],argv[1])) { if(argv[2]>argv[3]) printf("The difference is:%d\n",k-j); else printf("The difference is:%d\n",j-k); } else if(!strcmp(f[2],argv[1])) printf("The result is:%d\n",k*j); else { if(argv[3]==0)printf("I can not divide,because the 2nd term is 0\n"); else printf("The result is:%d\n",k/j); } system("Pause"); return 0; } Αυτός είναι ο κώδικας μαζί με τις πράξεις πολ/μου και διαίρεσης.Το πρόβλημα τώρα είναι ότι στην αφαίρεση,παρά τον έλεγχο που έχω ενσωματώσει,αφαιρεί πάντα το argv[2] απο το argv[3] και ποτέ το ανάποδο και στη διαίρεση μου εμφανίζει μόνο το δεύτερο σκέλος του ελέγχου. > if(argv[2]>argv[3]) printf("The difference is:%d\n",k-j); Το argv είναι char*[], επομένως συγκρίνεις char* μεταξύ τους -- και όχι τα strings στα οποία δείχνουν (που θα ήταν επίσης λάθος) ή τις ακέραιες τιμές που αναπαριστούν αυτά τα strings (που θα ήταν το σωστό). Βασικά δηλαδή αυτό που θέλεις είναι if (k > j). Το λάθος είναι σίγουρα προφανές απαξ και σου κάνει κλικ. Και ακόμα καλύτερα θα ήταν να βάλεις μια abs() γύρω από την αφαίρεση και να μην ασχοληθείς καθόλου με if. @Star_Light: Απόψε γύρισα από θάλασσα οπότε θα κάνω λίγα μόνο σχόλια καθως αν μη τι άλλο δεν έχω διαβάσει τις προηγούμενες σελίδες προσεκτικά. Για τα globals έχουμε ξαναπεί ότι "πρέπει" να αποφεύγονται. Προσωπικά με καλύπτει εν μέρει το σχόλιό σου ότι είναι συνειδητή επιλογή, με την έννοια ότι και γω αν έγραφα ένα πρόγραμμα για να κάνω μια βρωμοδουλειά στα γρήγορα δε θα καθόμουν να χάσω χρόνο δομώντας το σωστά (αφού έτσι κι αλλιώς μετά θα το πετάξω). Αυτή η αντιμετώπιση όμως να ξέρεις ότι "επιτρέπεται" μόνο όταν μιλάμε για κάτι που μπορείς να το κάνεις "σωστά" ακόμα και στον ύπνο σου. Στη δική σου περίπτωση συγκεκριμένα εφόσον είσαι ακόμα στο στάδιο που διαβάζεις τον King ίσως να προτρέχεις λίγο. Μπορείς μεν να το κάνεις χωρίς globals, αλλά πιθανόν όχι στον ύπνο σου. Αν ισχύει αυτό, μαστίγωσε τον εαυτό σου τώρα και θα δρέψεις τους καρπούς αργότερα. (Tip: δοκίμασε να εξηγήσεις προφορικά και χωρίς καμία προετοιμασία στην πάπια το πώς θα έκανες το πρόγραμμα χωρίς globals. Αν καταφέρεις να το κάνεις χωρίς να κολλήσεις πουθενά τότε πιθανότατα μπορείς να το κάνεις και στον ύπνο σου). Απο κει και πέρα για τα υπόλοιπα που είπαν τα παιδιά να έχεις open mind. Κανείς δεν είναι θεός να γράφει τον τέλειο κώδικα ακόμα και όταν τα κριτήρια είναι 100% αντικειμενικά (γιατί υπάρχουν και πολύ σημαντικά πλην όμως υποκειμενικά). Αν έχεις πραγματικά αμφιβολία για το αν είναι καλύτερο το Α ή το Β, θα σου πρότεινα να κάνεις το εξής: Γράψε τα προγράμματα Α και Β Για το κάθε ένα από αυτά, γράψε μια ανάλυση για ποιούς ακριβώς λόγους είναι καλύτερο από το άλλο (όσο μεγάλη νομίζεις ότι χρειάζεται) -- κατά προτίμηση με μολύβι και χαρτί, τουλάχιστον τις πρώτες φορές Προαιρετικά: πόσταρε τα προγράμματα και τις αναλύσεις σου μαζί και ζήτα σχόλια πάνω στις αναλύσεις σου Μετά από μερικές φορές δε θα χρειαστεί να φτάσεις καν στο #3. Δοκίμασέ το και πες μας αν είχε αποτέλεσμα. (βασικά πρόκειται για παραλλαγή του rubber ducking που είπα και παραπάνω με extra bonus το εγγράφως γιατί σε αναγκάζει να σκεφτείς αυτό που λες σε πολύ μεγαλύτερο βαθμό απ' οτι θα το έκανες αν δεν το έγραφες). Και τέλος ένα bonus link για το πόσο άσχημα μπορούν να πάνε τα πράγματα με μια global (το παραθέτω για χαβαλέ και όχι σαν επιχείρημα): http://blogs.msdn.co...04/9917053.aspx 3
imitheos Δημοσ. 12 Αυγούστου 2012 Δημοσ. 12 Αυγούστου 2012 Και τέλος ένα bonus link για το πόσο άσχημα μπορούν να πάνε τα πράγματα με μια global (το παραθέτω για χαβαλέ και όχι σαν επιχείρημα): http://blogs.msdn.co...04/9917053.aspx Χεχε, ωραίο. Καλά τι κώδικες γράφονταν τότε σε DOS δεν λέγεται. Globals παντού, pointers να τους δίνεται χύμα διεύθυνση (αν εξαιρέσουμε το ας πούμε δόκιμο παράδειγμα να δουλεύεις με την cmos στην 0x0040). Ό,τι ήθελες σε άφηνε το DOS να το κάνεις. Ένας Velociraptor κρυμμένος σε κάθε γωνία
migf1 Δημοσ. 13 Αυγούστου 2012 Δημοσ. 13 Αυγούστου 2012 Κοιταξε να δεις επειδη σεβομαι καποια πραγματα δεν θα συνεχισω τον αντιλογο. Εκτος αυτου δεν πειθεται καποιος με επιχειρηματα. Δεν ξεχναω τα λεγομενα μου. Απλα να χεις υποψιν σου οτι ποτε δεν έχεις πει έναν καλο λογο οταν επρεπε περα απο την αυστηρη κριτικη που κανεις. Δεν ξέρω τι εννοείς περί επιχειρημάτων, εγώ όμως προσπαθώ πάντα όσα γράφω να συνοδεύονται είτε με κώδικα, είτε με λινκς είτε και με τα δυο. Για τον καλό λόγο, πάλι δεν καταλαβαίνω... θεωρώ πως η ουσία σε ένα φόρουμ προγραμματισμού το πρωτεύον είναι η ανταλλαγή πληροφοριών προγραμματισμού ώστε να τσεκάρουμε/βελτιώνουμε τα skills μας και όχι οι εκατέρωθεν φιλοφρονήσεις. Όπως και να έχει, παραθέτω ακόμα μια υλοποίηση χωρίς καθόλου χρήση string, όπου τα πάντα γίνονται inplace. Δηλαδή η είσοδος επεξεργάζεται δυναμικά, χαρακτήρα προς χαρακτήρα χωρίς να αποθηκεύεται σε κανένα string. Άρα χρειαζόμαστε μονάχα έναν πίνακα, του ιστογράμματος. Το len είναι το πλήθος των έγκυρων γραμμάτων. Αν χρειαζόμαστε το συνολικό πλήθος (έγκυρων & άκυρων) τότε χρειάζεται έξτρα όρισμα. Είμαι σε διακοπές, οπότε το 'γραψα στο πόδι (χωρίς sanity checks, σχόλια, κλπ) νομίζω όμως πως δουλεύει σωστά. > #include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> #define MAXALPHAS 26 #define EXITCHAR '@' /************************************************/ int do_inplace( int hist[] ) { int i=0, c='\0'; while( '\n' != (c=getchar()) ) { if ( 0 == i && EXITCHAR == c ) return -1; if ( isalpha(c) ){ hist[ tolower(c) - 'a']++; i++; } } return i; } /************************************************/ int main( void ) { int hist[ MAXALPHAS ] = {0}; int len = 0; for (; { printf( "\nDwse protash (%c gia ejodo): ", EXITCHAR ); if ( -1 == (len=do_inplace(hist)) ) break; if ( 0 == len ) { puts( "kenh h mh egkyrh protash" ); continue; } for (int i = 0; i < MAXALPHAS; i++) if (hist[i] > 1) printf("To '%c' emfanisthke %3d fores\n", 'a' + i, hist[i]); memset( hist, 0, MAXALPHAS * sizeof(int) ); } exit(0); } Αν θέλουμε να κρατάμε την είσοδο σε ξεχωριστό string, η do_inplace() μπορεί να αλλάξει σε κάτι τέτοιο... > int do_inplace( char input[MAXINPUT], int hist[] ) { int i=0; while (i < MAXINPUT-1) { input[i] = getchar(); if ( 0 == i && EXITCHAR == input[i] ) return -1; if ( '\n' == input[i] ) break; if ( isalpha(input[i]) ){ hist[ tolower(input[i]) - 'a']++; i++; } } input[i] = '\0'; return ('\0' == *input) ? 0 : i; } με τις αντίστοιχες προσαρμογές στον υπόλοιπο κώδικα, και μετονομασμένη σε όνομα πιο αντιπροσωπευτικό. 1
migf1 Δημοσ. 15 Αυγούστου 2012 Δημοσ. 15 Αυγούστου 2012 ... P.S Διαβασα οτι μια συναρτηση θα πρεπει να κανει καθε φορα μια εργασια.... δεν ξερω κατα ποσο θα πειραζε καποια στιγμη να την βαλουμε να κάνει 2. Πχ να δεχεται απο τον χρηστη εισοδο και αυτοματα να αντιστρεφει και το string (αν θελουμε να κανει αντιστροφη). Θα πείραζε υπό την έννοια πως αν χρειαστεί να κάνεις πολλές ξεχωριστές εισόδους σε διάφορα σημεία του κώδικα ή πολλές ξεχωριστές αντιστροφές, τότε θα διπλο-γράψεις κώδικα. Ενώ αν έχεις μια συνάρτηση για είσοδο και μια για αντιστροφή, τότε μπορείς να τις χρησιμοποιείς αυτόνομα κατά βούληση όπου κι όταν χρειάζεται. Οπότε τυπικά δεν είναι λάθος να κάνεις πολλές δουλειές μέσα σε μια συνάρτηση (δεν επηρεάζει δηλαδή την λειτουργικότητα), αλλά μπορεί να λογιστεί ας πούμε ως bad-practice. Ή μπορεί να λογιστεί ας πούμε ως δείγμα που ξεχωρίζει έναν άπειρο από έναν έμπειρο προγραμματιστή. 1
Star_Light Δημοσ. 15 Αυγούστου 2012 Δημοσ. 15 Αυγούστου 2012 20 μηνυματα; Τι εχασα; Μας την ειπε ο ημιθεος επειδη λεει δεν καταλάβαμε οτι το -1 σαν EOF απο την συναρτηση που επιστρεφεται ειναι έξτρα τιμη στο extended ASCII αρα θα έχουμε 257 τιμές αντι για τις στανταρ 256 που εχει το προτυπο και επομενως θα ειναι προβλημα. Νταξει σημερα το διαβασα πρωτη φορα και για μενα να πω την αληθεια δεν ειναι παραλειψη του βιβλιου. Το βιβλιο σου δινει κάποιες εισαγωγικες βάσεις... δεν μπορει να στα καλυψει ολα. Ουτε να ειναι μεσα σε ολους τους ελεγχους ασφαλειας κτλπ. Επισης επειδη δεν του ειπαμε οτι απο 32 bit συστηματα σε 64 προφανως αυξάνεται το ευρος των αριθμων λογω εκθετη που μπορουν να αναπαρασταθουν μαλλον δεν καταλαβαινουμε τι διαβαζουμε. Αν θες παντως να κανεις τοοοοοοσο σχολαστικα checks. Ψαχνεσαι μονος σου μετα ή πληρωνεις παραπανω τον φουκαρά που έχεις προσλάβει ή εχεις 2-3 . Δεν μπορει ο ενας να τα σκεφτεται ολα......
Προτεινόμενες αναρτήσεις