17-11-14
17:23
παρακαλώ.Ευχαριστω!!
btw, τώρα πρόσεξα ότι σπουδάζεις Χημεία.
Απορώ γιατί σε τέτοιες σχολές σας ταλαιπωρούν με γλώσσα C. Λες και δεν υπάρχει η matlab ή διάφορα άλλα προγραμματιστικά εργαλεία για να κάνετε τη δουλειά σας.
Αν βέβαια μαθαίνεις C από επιλογή σου τότε οκ..
Σημείωση: Το μήνυμα αυτό γράφτηκε 9 χρόνια πριν. Ο συντάκτης του πιθανόν να έχει αλλάξει απόψεις έκτοτε.
07-03-12
23:23
Η ερωτηση μου ηταν απλα σε θεωρητικο επιπεδο . Δηλαδη αν αυτο που μπορεις να το κανεις με class μπορεις να το κανεις και με ενα struct. Δηλαδη απευθειας να ορισεις μεσα στο scope function member.
Οπως και να εχει, ευχαριστω για τις απαντησεις σας.
Σε περίπτωση που ψάχνεις κάτι ισοδύναμο και δε σε νοιάζει τόσο πολύ η συνάρτηση να είναι μέσα στη struct, μπορείς να κάνεις το εξής : ορίζεις τη struct με τις μεταβλητές που θέλεις και χωριστά ορίζεις μια συνάρτηση με όρισμα δείκτη προς αυτή τη struct (και ότι άλλα ορίσματα χρειάζεσαι). Είναι ακριβώς το ίδιο πράγμα με τις συναρτήσεις που έχει η java μέσα στις classes.
Σημείωση: Το μήνυμα αυτό γράφτηκε 12 χρόνια πριν. Ο συντάκτης του πιθανόν να έχει αλλάξει απόψεις έκτοτε.
31-12-11
11:08
Γεια σας! Χρόνια πολλά σε όλους, καλή πρωτοχρονιά!
Μου επιτρέπετε να συμμετάσχω κι εγώ στην παραπάνω κουβεντούλα;
Όπως σωστά ειπώθηκε, το αρχείο εισόδου κατά πάσα πιθανότητα είναι κωδικοποιημένο σε UTF-8. Στο UTF-8 οι χαρακτήρες δεν αναπαριστώνται όλοι με τον ίδο αριθμό bytes. Ο κάθε χαρακτήρας μπορεί να αναπαριστάται από 1 μέχρι 4 bytes.
Στο UTF-8 ο χαρακτήρας ’ αναπαριστάται με 3 bytes, και συγκεκριμένα τα : 226 128 153
Η fgetc διαβάζει κάθε φορά 1 byte. Συνεπώς, είναι απολύτως αναμενόμενη η έξοδος του προγράμματός σου.
Για επαλήθευση των παραπάνω, μπορείς να δοκιμάσεις τα εξής :
1) πρόσθεσε ένα αρχείο κειμένου τον χαρακτήρα ’ και σύγκρινε το μέγεθος του αρχείου πριν και μετά. Θα δεις ότι θα αλλάξει κατά 3 bytes.
2) Άλλαξε στον κώδικα το printf("%c",ch); με printf("%d ",ch); και το ch δήλωσέ ως unsigned. Θα δεις ότι στο σημείο όπου διαβάζει το ’ θα τυπώσει τους αριθμούς 226 128 153.
Και κάτι ακόμα που αξίζει να σημειώσουμε. Μπορεί η μέτρηση των χαρακτήρων να μη σου έδωσε το αποτέλεσμα που περίμενες, ωστόσο με την εντολή printf("%c",ch); το κείμενο τυπώνεται σωστά στην έξοδο, εφόσον το τερματικό όπου εκτελείται το πρόγραμμα είναι ρυθμισμένο (κατά πάσα πιθανότητα) κι αυτό σε UTF-8.
Δοκίμασε να τρέξεις τον κώδικα printf("%c%c%c",226,128,153); Το αποτέλεσμα θα είναι να εκτυπωθεί το ’
Μη θυμώνεις με τη C γιατί δε φταίει!
char = 1 byte.
Μέσα σε '' μπορούμε να βάλουμε μόνο 1 byte!
Το αρχείο με τον πηγαίο κώδικα μάλλον είναι κι αυτό σε UTF-8, όπου και το ’ και οι ελληνικοί χαρακτήρες είναι πάνω από 1 byte.
Ας πάρουμε για παράδειγμα τον κώδικα
ch = 'α';
printf("%c",ch);
Αν γράψεις τον κώδικα αυτό σε Greek ISO-8859-7 όπου το α είναι 1 byte και μετά τον ίδιο ακριβώς κώδικα τον γράψεις σε UFT-8 όπου το α είναι 2 bytes, στην πραγματικότητα γράφεις διαφορετικό κώδικα! Ο compiler δε καταλαβαίνει τι βλέπεις εσύ στην οθόνη, καταλαβαίνει ακολουθίες από bytes.
Με Greek ISO-8859-7 είναι σα να λες ch = 225 (η αναπαράσταση του α σε Greek ISO-8859-7). Η μεταγλώτισση του κώδικα σ' αυτή τη περίπτωση θα γίνει κανονικά, χωρίς warnings!
Με UFT-8 είναι σα να λες ch = 206 177 (η αναπαράσταση του α σε UTF-8 ) το οποίο προφανώς δε μπορεί να εκτελεστεί και γι αυτό σου βγάζει warning ότι γίνεται truncation και στο ch αποθηκεύει μόνο το λιγότερο σημαντικό byte (177).
Ας δούμε και τι θα εκτυπωθεί με την printf("%c",ch);
Αν ο κώδικας ήταν σε Greek ISO-8859-7, τότε θα εκτυπωθεί το α μόνο αν το τερματικό είναι κι αυτό σε Greek ISO-8859-7. Αν είναι σε UTF-8 τότε δε θα τυπώσει τίποτα αφού το 225 (bin 11100001) δεν είναι από μόνο του έγκυρος UTF-8 χαρακτήρας. Αν το τερματικό χρησιμοποιεί οποιαδήποτε άλλη κωδικοποίηση στην οποία το 225 είναι κάποιος χαρακτήρας, θα εκτυπωθεί ο χαρακτήρας αυτός.
Αντίστοιχα αν ο κώδικας ήταν σε UFT-8, τότε ανάλογα με την κωδικοποίηση του τερματικού θα εκτυπωθεί ο χαρακτήρας που αντιστοιχεί στον αριθμό 177.
so... γενικό συμπέρασμα : τέτοια προγράμματα για να εκτελεστούν σωστά θα πρέπει να υπάρχει συμβατότητα στα encodings που χρησιμοποιούνται στα αρχεία εισόδου, στο terminal όπου τρέχει το πρόγραμμα και στον source code.
Μάλλον αναφέρεσαι στο Windows-1252
Μπορείς να γράψεις ξεκάθαρα στην αναφορά που θα παραδώσεις ή στα σχόλια του κώδικα ότι η μέτρηση των χαρακτήρων θα γίνει σωστά όταν στο αρχείο εισόδου χρησιμοποιείται κωδικοποίση στην οποία κάθε χαρακτήρας είναι 1 byte.
Θα μπορούσες να γράψεις και κώδικα που αναγνωρίζει τη UTF-8 κωδικοποίηση και καταλαβαίνει σε ποιο byte τελειώνει ο κάθε χαρακτήρας, αλλά αυτό ξεφεύγει πολύ από τις απαιτήσεις της άσκησης.
Δε ξέρω ποιο text editor χρησιμοποιείς, καλό πάντως θα ήταν να εγκαταστήσεις κάποιον όπου να μπορεις να πειραματιστείς με διάφορα encodings. Σε linux μπορείς να χρησιμοποιήσεις gedit ή kate, σε windows το notepad++.
Μου επιτρέπετε να συμμετάσχω κι εγώ στην παραπάνω κουβεντούλα;
Όπως σωστά ειπώθηκε, το αρχείο εισόδου κατά πάσα πιθανότητα είναι κωδικοποιημένο σε UTF-8. Στο UTF-8 οι χαρακτήρες δεν αναπαριστώνται όλοι με τον ίδο αριθμό bytes. Ο κάθε χαρακτήρας μπορεί να αναπαριστάται από 1 μέχρι 4 bytes.
Για να επιτευχθεί αυτό, τα πιο σημαντικά bits του 1ου byte δείχουν το πλήθος των bytes. Αν το σημαντικότερο bit του 1ου byte είναι 0, τότε ο χαρακτήρας έχει 1 byte και τα υπόλοιπα 7 bits αναπαριστούν τους 2^7=128 ASCII χαρακτήρες.
Αν το 1ο byte ξεκινάει με 110, τότε ο χαρακτήρας έχει 2 byte, αν ξεκινάει με 1110 έχει 3 byte και τέλος αν ξεκινάει με 11110 έχει 4 byte. Όταν ένα byte αρχίζει με 10, τότε πρόκειται για το 2ο, 3ο ή 4ο byte κάποιου χαρακτήρα.
Κάποια σημαντικά πλεονεκτήματα με την αναπαράσταση αυτή : 1) μεγάλος πλήθος (2^21) διαφορετικών χαρακτήρων που μπορούν να αναπαρασταθούν, 2) οι χαρακτήρες που στατιστικά εμφανίζονται συχνότερα έχουν κωδικοποιηθεί έτσι ώστε να έχουν μικρό αριθμό bytes , 3) δυνατότητα ανίχνευσης λαθών, πχ ένα byte που αρχίζει με 0 δε μπορεί να ακολουθείται από byte που αρχίζει με 10. 4) Συμβατότητα με την ASCII κωδικοποίηση. Ένα αρχείο κειμένου που έχει μόνο ASCII χαρακτήρες θα είναι ακριβώς το ίδιο και σε ASCII και σε UTF-8.
Αν το 1ο byte ξεκινάει με 110, τότε ο χαρακτήρας έχει 2 byte, αν ξεκινάει με 1110 έχει 3 byte και τέλος αν ξεκινάει με 11110 έχει 4 byte. Όταν ένα byte αρχίζει με 10, τότε πρόκειται για το 2ο, 3ο ή 4ο byte κάποιου χαρακτήρα.
Κάποια σημαντικά πλεονεκτήματα με την αναπαράσταση αυτή : 1) μεγάλος πλήθος (2^21) διαφορετικών χαρακτήρων που μπορούν να αναπαρασταθούν, 2) οι χαρακτήρες που στατιστικά εμφανίζονται συχνότερα έχουν κωδικοποιηθεί έτσι ώστε να έχουν μικρό αριθμό bytes , 3) δυνατότητα ανίχνευσης λαθών, πχ ένα byte που αρχίζει με 0 δε μπορεί να ακολουθείται από byte που αρχίζει με 10. 4) Συμβατότητα με την ASCII κωδικοποίηση. Ένα αρχείο κειμένου που έχει μόνο ASCII χαρακτήρες θα είναι ακριβώς το ίδιο και σε ASCII και σε UTF-8.
Στο UTF-8 ο χαρακτήρας ’ αναπαριστάται με 3 bytes, και συγκεκριμένα τα : 226 128 153
226 (dec) = 11100010 (bin)
128 (dec) = 10000000 (bin)
153 (dec) = 10011001 (bin)
Παρατηρούμε ότι τα πρώτα bits κάθε αριθμού έρχονται σε συμφωνία με αυτά που ανέφερα πριν για το UTF-8.
128 (dec) = 10000000 (bin)
153 (dec) = 10011001 (bin)
Παρατηρούμε ότι τα πρώτα bits κάθε αριθμού έρχονται σε συμφωνία με αυτά που ανέφερα πριν για το UTF-8.
Για επαλήθευση των παραπάνω, μπορείς να δοκιμάσεις τα εξής :
1) πρόσθεσε ένα αρχείο κειμένου τον χαρακτήρα ’ και σύγκρινε το μέγεθος του αρχείου πριν και μετά. Θα δεις ότι θα αλλάξει κατά 3 bytes.
2) Άλλαξε στον κώδικα το printf("%c",ch); με printf("%d ",ch); και το ch δήλωσέ ως unsigned. Θα δεις ότι στο σημείο όπου διαβάζει το ’ θα τυπώσει τους αριθμούς 226 128 153.
Και κάτι ακόμα που αξίζει να σημειώσουμε. Μπορεί η μέτρηση των χαρακτήρων να μη σου έδωσε το αποτέλεσμα που περίμενες, ωστόσο με την εντολή printf("%c",ch); το κείμενο τυπώνεται σωστά στην έξοδο, εφόσον το τερματικό όπου εκτελείται το πρόγραμμα είναι ρυθμισμένο (κατά πάσα πιθανότητα) κι αυτό σε UTF-8.
Δοκίμασε να τρέξεις τον κώδικα printf("%c%c%c",226,128,153); Το αποτέλεσμα θα είναι να εκτυπωθεί το ’
Αρχικα πηγα και εκανα copy/paste τον χαρακτηρα απο το κειμενο και εβαλα στην if το ch!='τον χαρακτηρα' . Κατα τη ΜΕΤΑΓΛΩΤΙΣΗ του κειμενου μου πετα ΠΡΟΕΙΔΟΠΟΙΗΣΗ multi-character character constant [-Wmultichar] .
Πληκτρολογοντας στο google τι σκατα ειναι το multi character moy bgale oyte ligo oyte poly oti δεν "μπορεις" να του βαλεις ' ' γιατι δεν θεωρειται ενας χαρακτηρας για την C.
Μη θυμώνεις με τη C γιατί δε φταίει!
char = 1 byte.
Μέσα σε '' μπορούμε να βάλουμε μόνο 1 byte!
Το αρχείο με τον πηγαίο κώδικα μάλλον είναι κι αυτό σε UTF-8, όπου και το ’ και οι ελληνικοί χαρακτήρες είναι πάνω από 1 byte.
Ας πάρουμε για παράδειγμα τον κώδικα
ch = 'α';
printf("%c",ch);
Αν γράψεις τον κώδικα αυτό σε Greek ISO-8859-7 όπου το α είναι 1 byte και μετά τον ίδιο ακριβώς κώδικα τον γράψεις σε UFT-8 όπου το α είναι 2 bytes, στην πραγματικότητα γράφεις διαφορετικό κώδικα! Ο compiler δε καταλαβαίνει τι βλέπεις εσύ στην οθόνη, καταλαβαίνει ακολουθίες από bytes.
Με Greek ISO-8859-7 είναι σα να λες ch = 225 (η αναπαράσταση του α σε Greek ISO-8859-7). Η μεταγλώτισση του κώδικα σ' αυτή τη περίπτωση θα γίνει κανονικά, χωρίς warnings!
Με UFT-8 είναι σα να λες ch = 206 177 (η αναπαράσταση του α σε UTF-8 ) το οποίο προφανώς δε μπορεί να εκτελεστεί και γι αυτό σου βγάζει warning ότι γίνεται truncation και στο ch αποθηκεύει μόνο το λιγότερο σημαντικό byte (177).
Ας δούμε και τι θα εκτυπωθεί με την printf("%c",ch);
Αν ο κώδικας ήταν σε Greek ISO-8859-7, τότε θα εκτυπωθεί το α μόνο αν το τερματικό είναι κι αυτό σε Greek ISO-8859-7. Αν είναι σε UTF-8 τότε δε θα τυπώσει τίποτα αφού το 225 (bin 11100001) δεν είναι από μόνο του έγκυρος UTF-8 χαρακτήρας. Αν το τερματικό χρησιμοποιεί οποιαδήποτε άλλη κωδικοποίηση στην οποία το 225 είναι κάποιος χαρακτήρας, θα εκτυπωθεί ο χαρακτήρας αυτός.
Αντίστοιχα αν ο κώδικας ήταν σε UFT-8, τότε ανάλογα με την κωδικοποίηση του τερματικού θα εκτυπωθεί ο χαρακτήρας που αντιστοιχεί στον αριθμό 177.
so... γενικό συμπέρασμα : τέτοια προγράμματα για να εκτελεστούν σωστά θα πρέπει να υπάρχει συμβατότητα στα encodings που χρησιμοποιούνται στα αρχεία εισόδου, στο terminal όπου τρέχει το πρόγραμμα και στον source code.
Πήγαινε Αρχείο-->Αποθήκευση ως και επέλεξε κωδικοποίηση ANSI.
Μάλλον αναφέρεσαι στο Windows-1252
Δεν εχει ASCII ,ασε που και να το ειχε και εγω να καταφερνα να μετρησω σωστα οταν θα την ελεγχε ο καθηγητης μπορει να εβαζε ενα οποιοδηποτε αρχειο μεσα και να μην ειχε τετοια κωδικοποιηση.
Μπορείς να γράψεις ξεκάθαρα στην αναφορά που θα παραδώσεις ή στα σχόλια του κώδικα ότι η μέτρηση των χαρακτήρων θα γίνει σωστά όταν στο αρχείο εισόδου χρησιμοποιείται κωδικοποίση στην οποία κάθε χαρακτήρας είναι 1 byte.
Θα μπορούσες να γράψεις και κώδικα που αναγνωρίζει τη UTF-8 κωδικοποίηση και καταλαβαίνει σε ποιο byte τελειώνει ο κάθε χαρακτήρας, αλλά αυτό ξεφεύγει πολύ από τις απαιτήσεις της άσκησης.
Δε ξέρω ποιο text editor χρησιμοποιείς, καλό πάντως θα ήταν να εγκαταστήσεις κάποιον όπου να μπορεις να πειραματιστείς με διάφορα encodings. Σε linux μπορείς να χρησιμοποιήσεις gedit ή kate, σε windows το notepad++.
Σημείωση: Το μήνυμα αυτό γράφτηκε 12 χρόνια πριν. Ο συντάκτης του πιθανόν να έχει αλλάξει απόψεις έκτοτε.