migf1 Δημοσ. 15 Νοεμβρίου 2012 Δημοσ. 15 Νοεμβρίου 2012 Και τι θα κερδίσει με το (int) cast ? Απολύτως τίποτα, σωστός! Οπότε no cast όταν signed char.
imitheos Δημοσ. 15 Νοεμβρίου 2012 Δημοσ. 15 Νοεμβρίου 2012 Απολύτως τίποτα, σωστός! Οπότε no cast όταν signed char. Όπως και να χει όμως είτε με cast ή χωρίς και με signed και με unsigned δεν υπάρχει σωτηρία. Η μόνη λύση είναι να χρησιμοποιηθεί int. Ξαναβάζω το ίδιο παράδειγμα που είχα δώσει και στο άλλο νήμα. > #include <stdio.h> #include <stdlib.h> int main(void) { FILE *f; f = fopen("test","w"); if (!f) return -1; fputs("Test\xFFHello World", f); fclose(f); return 0; } > #include <stdio.h> #include <stdlib.h> int main(void) { FILE *f; signed char ch; f = fopen("test", "r"); if (!f) return -1; while ((ch = fgetc(f)) != EOF) printf("%c\n", ch); return 0; } > Έξοδος: T e s t Το Hello World δεν εμφανίζεται ποτέ. Σε περίπτωση που το EOF δηλώνεται με άλλη τιμή (οπωσδήποτε αρνητική), τότε απλά θα χρειαστεί ένας άλλος χαρακτήρας από τον 0xFF για να σταματήσει εκεί η λειτουργία. 1
migf1 Δημοσ. 15 Νοεμβρίου 2012 Δημοσ. 15 Νοεμβρίου 2012 Πλήρης ανάλυση εδώ: http://en.wikibooks.org/wiki/C_Programming/File_IO#EOF_pitfall
Star_Light Δημοσ. 15 Νοεμβρίου 2012 Δημοσ. 15 Νοεμβρίου 2012 Καλημέρα. Μπορει κάποιος να αποφύγει τον έλεγχο για EOF? Ειδικα οταν δεν έχει φτιάξει το προγραμμα να δέχεται εισοδο απο αρχεία παρα τον ενδιαφέρει μονο μια line αρα και το τελος αυτης της γραμμης ('\n') και οχι το τέλος του αρχειου.
migf1 Δημοσ. 15 Νοεμβρίου 2012 Δημοσ. 15 Νοεμβρίου 2012 Καλημέρα. Μπορει κάποιος να αποφύγει τον έλεγχο για EOF? Ειδικα οταν δεν έχει φτιάξει το προγραμμα να δέχεται εισοδο απο αρχεία παρα τον ενδιαφέρει μονο μια line αρα και το τελος αυτης της γραμμης ('\n') και οχι το τέλος του αρχειου. Στην stdin το EOF αναπαράγεται με διαφορετικό συνδυασμό πλήκτρων, ανάλογα το τερματικό. Οι συνηθέστεροι είναι Ctr+D και Ctrl+Z (αλλά συνέχεια ξεχνάω ποιος είναι σε Windows και ποιος σε *nix τερματικά). Μπορείς να τον παρακάμψεις και τελείως, σιγά μη σου πατήσει Ctrl+D/Z ... και να σου πατήσει πολύ που σε νοιάζει, θα βάλεις και το -1 μέσα στο signed char input σου. Btw, να και πως θα μπορούσες να το κάνεις αμιγώς με int... > #include <stdio.h> #define MAXINPUT (255+1) /* --------------------------------------------------- */ int main( void ) { int input[MAXINPUT] = {'\0'}; int *cp = input + MAXINPUT-2; printf("%s", "Enter a message : "); fflush(stdout); while ( '\n' != (*cp = getchar()) && EOF != *cp && cp != input ) cp--; cp = ('\n' == *cp || EOF == *cp) ? cp+1 : cp; // like puts() but with int type while ( *cp ) putchar( *cp++ ); putchar( '\n' ); return 0; }
Star_Light Δημοσ. 15 Νοεμβρίου 2012 Δημοσ. 15 Νοεμβρίου 2012 Oκ θα το κρατήσω οπως το εχεις στο τελευταιο σου ποστ.... απλα πασχιζα να σκεφτω εναν τροπο να αποφυγω τα 2 loops. Ενιγουει. Ευχαριστω
imitheos Δημοσ. 15 Νοεμβρίου 2012 Δημοσ. 15 Νοεμβρίου 2012 (επεξεργασμένο) Στην stdin το EOF αναπαράγεται με διαφορετικό συνδυασμό πλήκτρων, ανάλογα το τερματικό. Οι συνηθέστεροι είναι Ctr+D και Ctrl+Z (αλλά συνέχεια ξεχνάω ποιος είναι σε Windows και ποιος σε *nix τερματικά). Σε *nix το Ctrl+D είναι το EOF και το Ctrl+Z πάει την διεργασία στο παρασκήνιο. Edit: Αν μας καίει η μνήμη, μπορεί να δηλωθεί char ο πίνακας και η getchar να αποθηκεύεται σε μια προσωρινή int μεταβλητή ή ακόμη καλύτερα να χρησιμοποιήσουμε fgets και να ησυχάσουμε. > #include <stdio.h> #include <string.h> #define MAXINPUT (255+1) /* Μαμάτο σχόλιο */ /* --------------------------------------------------- */ int main( void ) { char input[MAXINPUT] = {'\0'}; size_t len; printf("%s", "Enter a message : "); fflush(stdout); fgets(input, MAXINPUT, stdin); len = strlen(input); /* Αφαίρεση της πιθανής newline. Στο συγκεκριμένο κώδικα * και να μείνει δεν μας νοιάζει */ if (input[len - 1] == '\n') { input[len - 1] = '\0'; len--; } /* Προσοχή: ποτέ >= 0 γιατί έχουμε size_t */ while (len > 0) putchar(input[--len]); putchar('\n'); return 0; } Επεξ/σία 15 Νοεμβρίου 2012 από imitheos
migf1 Δημοσ. 15 Νοεμβρίου 2012 Δημοσ. 15 Νοεμβρίου 2012 @StarLight: Και η puts() ένα loop με fputc() είναι συνήθως. @imitheos: Δεν το τεστάρισα, αλλά όπως το βλέπω, τυπώνει όλους τους χαρακτήρες αν σου δώσει input με MAXINPUT-1 χαρακτήρες; EDIT: Δεν δουλεύει, το τεστάρισα
imitheos Δημοσ. 15 Νοεμβρίου 2012 Δημοσ. 15 Νοεμβρίου 2012 Δεν το τεστάρισα, αλλά όπως το βλέπω, τυπώνει όλους του χαρακτήρες αν σου δώσει input με MAXINPUT-1 χαρακτήρες; Η fgets διαβάζει πάντα ένα χαρακτήρα λιγότερο για να γράψει το \0 οπότε εφόσον το MAXINPUT είναι 256, θα διαβάσει/τυπώσει μέχρι και 255 χαρακτήρες.
migf1 Δημοσ. 15 Νοεμβρίου 2012 Δημοσ. 15 Νοεμβρίου 2012 Δοκίμασέ το με... #define MAXINPUT (3+1) και δώσε του input: 123
imitheos Δημοσ. 15 Νοεμβρίου 2012 Δημοσ. 15 Νοεμβρίου 2012 Δοκίμασέ το με... #define MAXINPUT (3+1) και δώσε του input: 123 Ναι έφταιγε το len-- που δεν θα έπρεπε να τρέχει αν δεν υπάρχει χώρος για την newline. Off by one errors rulez.
fonsde Δημοσ. 16 Νοεμβρίου 2012 Δημοσ. 16 Νοεμβρίου 2012 μπορει καποιος να μου εξηγησει το cast του ιντ? > void main(){ int a = 6; char* x = (char*) a; a = 7; printf("%d",x); }
imitheos Δημοσ. 16 Νοεμβρίου 2012 Δημοσ. 16 Νοεμβρίου 2012 μπορει καποιος να μου εξηγησει το cast του ιντ? > void main(){ int a = 6; char* x = (char*) a; a = 7; printf("%d",x); } Αν κρίνουμε από το void main και τη χρήση του int σε δείκτη, τον κώδικα αυτόν τον διάβασες σε κάποιο πολύ παλιό βιβλίο για DOS ή Turbo C ? Θα προσπαθήσω να εξηγήσω τι κάνει αλλά όπως τον είδες ξέχασε τον και αν είναι από βιβλίο κρύψε το βιβλίο κάπου που να μην μπορεί να το βρει κανείς ποτέ > int a = 6; Αυτό είναι εύκολο και απλά δηλώνει μια ακέραια μεταβλητή και της δίνει την τιμή 6. > 1) char *x = a; 2) char *x = (char *)a; Ας δούμε πρώτα το 1. Δηλώνει ένα δείκτη σε χαρακτήρα και του θέτει ως τιμή την τιμή του a (προσοχή όχι την διεύθυνση όπως δίνουμε συνήθως σε δείκτες αλλά την τιμή) δηλαδή ο x πλέον δείχνει στην διεύθυνση μνήμης 6. Επειδή όμως η μεταβλητή a είναι ακέραια και δεν έχει σχέση με δείκτες, ο compiler θα μας βγάλει μήνυμα "τι κάνεις ρε ?" για αυτό βάζουμε το cast ώστε να σωπάσουμε τον compiler δηλώνοντας ότι "θέλω την a να την μεταχειριστείς σαν να ήταν δείκτης σε char". > printf("%d",x); Αν είχαμε *x τότε θα προσπαθούσε να προσπελάσει την διεύθυνση μνήμης 6 και να μας εμφανίσει την εκεί τιμή. Εμείς όμως έχουμε σκέτο x οπότε απλά τυπώνει την τιμή της μεταβλητής x σαν να ήταν ακέραιος δηλαδή θα εμφανίσει τον αριθμό 6.
migf1 Δημοσ. 16 Νοεμβρίου 2012 Δημοσ. 16 Νοεμβρίου 2012 > int main( void ) { int a = 6; char *x = (char *)a; // x treats a as if it was an address a = 7; // useless regarding x (no side-effects whatsoever) printf("%d", x); } !!! DO NOT USE SUCH PRACTICES !!!! EDIT: Με πρόλαβε ο imitheos.
Προτεινόμενες αναρτήσεις