migf1 Δημοσ. 8 Ιουνίου 2011 Δημοσ. 8 Ιουνίου 2011 Καλησπέρα, με αφορμή ένα σχετικό post σε άλλο φόρουμ, επιχείρησα σήμερα να φτιάξω ένα απλό προγραμματάκι σε standard C το οποίο να διαβάζει από την κονσόλα ελληνικά strings, να τα διαχειρίζεται και να τα τυπώνει επίσης στη κονσόλα (σε Windows 7 και Windows XP). Θυμόμουν από παλιά πως ένας από τους πιο εύκολους τρόπους ήταν με χρήση της στάνταρ συνάρτησης setlocale() (link-1, link-2, link-3). Ξεκίνησα πρώτα με 8-μπιτες κωδικοσελίδες δοκιμάζοντας τον κώδικα τόσο σε MinGW όσο και σε Pelles-C. Σε Pelles-C το εκτελέσιμο δουλεύει μια χαρά, αλλά σε MinGW αρνείται πεισματικά να τυπώσει σωστά όσα strings έχουν διαβαστεί με στάνταρ συναρτήσεις διαβάσματος (παρόλο που όσα strings τα τυπώνω ως σταθερές τυπώνονται κανονικά). Η setlocale() ξεκινώντας κανονικά διαβάζει από το περιβάλλον 3 environment variables: LC_CTYPE, LCA_ALL και LANG, τα οποία σε περιβάλλον Windows δεν υπάρχουν (και δεν δοκίμασα καν να τα ορίσω). Δεν ξέρω τι ακριβώς παίζει εδώ, αλλά είδα πως η Pelles-C ξεκινάει με locale string "C" (που είναι το συμβατό default και συνήθως ισούται με το locale string "POSIX") και αλλάζοντάς το σε "GR" (σύμφωνα με την τεκμηρίωσή της) το γυρίζει ΜΑΛΛΟΝ σε κωδικοσελίδα 737, αφού αυτή είναι η default κωδικοσελίδα της γραμμής εντολών στα Ελληνικά Windows και όλα δουλεύουν ρολόι. Ο MinGW από την άλλη ξεκινάει επίσης με locale string "C" αλλά μετά το... χάος! Γνωρίζω πως ο MinGW δεν υποστηρίζει POSIX και πως τα environment variables που χρειάζεται τα ορίζει σε ένα δικό του text αρχείο που το προσθέτει στα environment variables των Windows. Δεν θυμάμαι σε ποιο αρχείο είναι, αλλά είμαι σίγουρος πως ΔΕΝ τα ορίζει αυτά τα environment variables, αφενός γιατί είναι μεταβλητές POSIX κι αφετέρου γιατί δεν εμφανίζονται όταν ζητάω λίστα όλων των environment variables, είτε από msys είτε από την κανονική γραμμή εντολών. Διαβάζοντας λοιπόν την τεκμηρίωση του gcc είδα πως σε περιβάλλον POSIX το locale string για τα Ελληνικά είναι είτε "el_GR" για 8-μπιτο charmap είτε "el_GR.UTF-8" για UTF-8. Κανένα από τα 2 τους δεν λειτουργεί στον MinGW. Ένα πιο γενικό locale string για τα ελληνικά είναι το "ell", το οποίο ναι μεν το δέχεται ο MinGW, αλλά το μετατρέπει σε κωδικοσελίδα Windows-1253 που είναι η default Windows κωδικοσελίδα των Ελληνικών Windows (το ίδιο κάνει και με το locale string "greek" που κανονικά είναι μόνο για Windows και χρησιμοποιείται π.χ. από το Visual Studio). Το ότι γυρίζει σε αυτή την κωδικοσελίδα το διασταυρώνω και μέσα στο πρόγραμμα, αφού τα σχετικά printf() που έχω συμπεριλάβει μου βγάζουν ως αποτέλεσμα το locale string "Greek_Greece.1253". Αυτό με κάνει να αναρωτιέμαι αν και το locale string "GR" της Pelles-C το γυρίζει επίσης σε κωδικοσελίδα Windows 1253 και όχι DOS 737. Εκεί δεν έχω τρόπο να το διασταυρώσω (τα σχετικά printf() μου επιστρέφουν το αρχικό "GR") αλλά με κάνει να αναρωτιέμαι αν αυτή η διαφορά είναι η αιτία που στη γραμμή εντολών το πρόγραμμα δουλεύει σωστά με Pelles-C αλλά με MinGW τυπώνει ερωτηματικά όταν τυπώνω strings που έχουν διαβαστεί με στανταρ συναρτήσεις (υπενθυμίζω πως τα string literals τα τυπώνει μια χαρά και ο MinGW). Γνωρίζει κανείς αν όντως υπάρχουν διαφορές σε επίπεδο ASCII μεταξύ DOS 737 και Windows 1253; Η γραμμή εντολών τρέχει guaranteed σε DOS 737, αφού το επιβεβαιώνει κι η εντολή: chcp (ή έτσι τουλάχιστον πιστεύω, υπάρχει άλλος τρόπος διασταύρωσης; ) Στον MinGW δοκίμασα να ορίσω χειροκίνητα "Greek_Greece.737" στην setlocale() κι ενώ σετάρει κανονικά την κωδικοσελίδα όταν εκτελείται το πρόγραμμα, εν τούτοις δεν τυπώνει πια ούτε καν τα string literals. Και μάλιστα αυτή τη φορά οι Ελληνικοί χαρακτήρες δεν βγαίνουν σαν αγγλικά ερωτηματικά, αλλά σαν σύμβολα ASCII με code πάνω από 127. Το ένα πρόβλημα λοιπόν είναι αυτό. Γνωρίζει κανείς ποιο locale string πρέπει να χρησιμοποιηθεί στην setlocale() ώστε όταν το πρόγραμμα γίνεται compile με MinGW να τυπώνει σωστά και τα strings και τα string literals? Το άλλο πρόβλημα είναι το UTF-8. Από τη μια, στην Pelles-C δεν έχω βρει ποιο locale string αντιστοιχεί σε UTF-8 κι από την άλλη, το POSIX documented locale string "el_GR.UTF-8" (και τα συναφή: "en_US.UTF-8", "en_UK.UTF-8", κλπ) δεν υποστηρίζονται ούτε από τον MinGW ούτε από την Pelles-C. Όπως δεν υποστηρίζεται και τα locale strings: "C.UTF-8" και "C_UTF8" που υποστηρίζονται σε παλιότερους compilers, όπως π.χ. της Borland (τα locale strings είναι implementation dependent). Οπότε για παράδειγμα, και σε συνδυασμό με την έλλειψη των σχετικών environment variables, αυτό εδώ το προγραμματάκι δεν δουλεύει σε περιβάλλον Windows (btw, η σελίδα του link είναι πολύ καλή). Παραθέτω τον κώδικα που έχω γράψει για 8-μπιτα charmaps με την ελπίδα πως θα βρεθεί κάποιος που θα ξέρει πως να τον κάνουμε να δουλεύει σωστά και με MinGW. Αν όχι, τουλάχιστον πως μπορεί να μετατραπεί ώστε να δουλεύει με UTF-8 στην κονσόλα των Windows. Και τέλος, μπορεί κάποιος με πρόσβαση σε Unix/Linux ή έστω με εγκατεστημένο το Cygwin στα Windows να επιβεβαιώσει ή να διαψεύσει πως λειτουργούν τα locale strings: "el_GR" και "el_GR.UTF-8" με τον παρακάτω κώδικα; > /* * In POSIX environmets we would set locale to "el_GR.UTF-8" * and possibly play with the wchar_t data type & functions * in order to convert to and from regular multibyte strings. * In Windows command line however the above locale is not working * and the ones I'm using below are NON UTF-8 aware */ /* * locale strings for various compilers * ( for more pre-proccessor directives see: * http://predef.sourceforge.net/precomp.html ) */ #if _MSC_VER // Visual Studio #define LOCALE_GR "greek" #elif __MINGW32__ // MinGW #define LOCALE_GR "ell" // equivallent to: "greek"... gives "Greek_Greece.1253" //#elif __GNUC__ //#define LOCALE_GR "el_GR.UTF-8" #elif __POCC__ // Pelles-C #define LOCALE_GR "GR" #endif #include <stdio.h> #include <stdlib.h> #include <locale.h> #include <string.h> #define MAXSLEN 255+1 #define MAXSLEN_LOCALE 100+1 #define couldnot "*** could not change locale" // *********************************************************** char *s_get(char *s, size_t len) { register char *cp; for (cp=s; (*cp=getc(stdin)) != '\n' && (cp-s) < len-1; cp++ ) ; // for-loop with empty body */ *cp = '\0'; // null-terminate last character return s; } // *********************************************************** int main( void ) { char *cp = NULL; char s1[ MAXSLEN ] = "", s2[ MAXSLEN ] = ""; char oldlocale[ MAXSLEN_LOCALE ] = ""; // get current locale cp = setlocale(LC_ALL, NULL); strncpy( oldlocale, cp, MAXSLEN_LOCALE ); printf("Current locale: %s\n", oldlocale); // change locale to Greek printf("attempting to set locale: %s\n", LOCALE_GR ); cp = setlocale(LC_ALL, LOCALE_GR); // cp = setlocale(LC_ALL, "el_GR.UTF-8"); if ( !cp ) puts( couldnot ); else printf("Locale changed to: %s\n", cp); // test Greek locale puts("\nκείμενο στα Ελληνικά\n"); // test output puts("\nΕκκίνηση Δοκιμών\n----------------"); printf("πληκτρολογήστε s1: "); // test input fflush(stdin); s_get(s1, MAXSLEN); printf("s1: "); puts(s1); printf("\nπληκτρολογήστε s2: "); fflush(stdin); s_get(s2, MAXSLEN); printf("s2: "); puts(s2); // test strlen printf("\n> strlen(s1): %d\t\tstrlen(s2): %d\n", (int)strlen(s1), (int)strlen(s2) ); // test strcmp printf( "> strcmp(s1, s2):\tτο s1 %sείναι ίδιο με το s2\n", !strcmp(s1, s2) ? "" : "δεν " ); // test strstr printf( "> strstr(s2, s1):\tτο s1 %sπεριέχεται στο s2\n", strstr(s2, s1) ? "" : "δεν " ); strncat(s1, s2, MAXSLEN-1 ); // test strcat printf("> strcat(s1, s2):\t%s\n", s1); // reset to original locale printf("\nπατήστε ENTER για τερματισμό "); if ( cp ) { if ( setlocale(LC_ALL, oldlocale) ) printf("(locale changed back to: %s)...", oldlocale); else puts( couldnot ); } fflush(stdin); getchar(); exit(0); }
ΠάρηςΓ Δημοσ. 8 Ιουνίου 2011 Δημοσ. 8 Ιουνίου 2011 Βιαζομαι να φυγω αλλα για δειξει η console UTF8 στα win πρεπει να δεις το CONSOLE API Console http://msdn.microsoft.com/en-us/library/ms686013(v=vs.85).aspx και απο εδω οριζεις utf8 List CP Αλλα θελει και αλλα fonts..Δε ξερω αν βοηθησα.
migf1 Δημοσ. 8 Ιουνίου 2011 Μέλος Δημοσ. 8 Ιουνίου 2011 Thanks για την απάντηση. Ναι αυτές είναι οι κωδικοσελίδες που ορίζεις με την εντολή: chcp στη γραμμή εντολών. Τα έχω δοκιμάσει, δυστυχώς χωρίς αποτέλεσμα
Directx Δημοσ. 8 Ιουνίου 2011 Δημοσ. 8 Ιουνίου 2011 Οι θέσεις του επεκταμένου ASCII διαφέρουν μεταξύ της 737 & 1253 CP , για περισσότερα συμβουλέψου τους πίνακες εδώ και εδώ. Από εκεί και πέρα, όσον αφορά την Console, από όσο γνωρίζω δεν υποστηρίζει Unicode CP (η 65001 τελικά καταργήθηκε -άλλοι ισχυρίζονται ότι δουλεύει, στα XP μου πάντως δεν..) οπότε θα πρέπει να περιορισθείς στην χρήση κάποιας ελληνικής κωδικοσελίδας είτε με την βοήθεια του εργαλείου CHCP ή με την βοήθεια του Windows API.
migf1 Δημοσ. 8 Ιουνίου 2011 Μέλος Δημοσ. 8 Ιουνίου 2011 Ευχαριστώ για την απάντηση DirectX, η χρήση του Windows API δυστυχώς κάνει defeat την αρχική πρόθεση για όσο το δυνατόν πιο συμβατό κώδικα, που είναι και ο βασικός λόγος που προτίμησα να χρησιμοποιήσω την setlocale() in the first place. Υποτίθεται πως ειδικά για UTF-8 οι στάνταρ συναρτήσεις διαχείρισης strings στην ANSI C δουλεύουν απείραχτες (με κάποιες εξαιρέσεις που δεν θυμάμαι απ' έξω τώρα) εκμεταλλευόμενες το γεγονός πως το ASCII table εμπεριέχεται ουσιαστικά ατόφιο μέσα στο UTF-8. Σε ότι αφορά την κωδικοσελίδα 65001 (UTF-8) στα δικά μου XP τη σετάρει κανονικά μέσα στη γραμμή εντολών με chcp, αλλά θα πρέπει να τσεκάρω αύριο στη δουλειά τι ακριβώς γίνεται στα Windows 7. Το βασικό πρόβλημα δεν έγκειται στο σετάρισμα της γραμμής εντολών (αυτό στο φινάλε το σετάρεις με ένα batch file, μέσα από το οποίο καλείς και το πρόγραμμα σου (μου ) ). Το πρόβλημα έγκειατι στο locale string που πρέπει να περαστεί στην setlocale() για υποστήριξη UTF-8, όταν ο κώδικας γίνεται compile σε περιβάλλον Windows (αντί για Unix). Που δυστυχώς και είναι implementation dependent και δεν μπορώ να το βρω πουθενά για MinGW και Pelles-C (για Visual Studio δεν έχω ψάξει καν, γιατί δεν το χρησιμοποιώ). ΥΓ. Μήπως δοκίμασε κανείς τον κώδικα σε native περιβάλλον POSIX να μας πει τουλάχιστον αν λειτουργεί as expected με 8-μπιτο locale string "el_GR" αφενός και με UTF-8 "el_GR.UTF-8" αφετέρου;
παπι Δημοσ. 9 Ιουνίου 2011 Δημοσ. 9 Ιουνίου 2011 Υποτίθεται πως ειδικά για UTF-8 οι στάνταρ συναρτήσεις διαχείρισης strings στην ANSI C δουλεύουν απείραχτες Το utf8 δεν ειναι ενα byte
migf1 Δημοσ. 9 Ιουνίου 2011 Μέλος Δημοσ. 9 Ιουνίου 2011 Το utf8 δεν ειναι ενα byte Ναι το γνωρίζω αυτό, αλλά το link που έχω στο αρχικό ποστ γράφει συγκεκριμένα: Many of C’s string functions are locale-independent and they just look at zero-terminated byte sequences: strcpy strncpy strcat strncat strcmp strncmp strdup strchr strrchr strcspn strspn strpbrk strstr strtok Some of these (e.g. strcpy) can equally be used for single-byte (ISO 8859-1) and multi-byte (UTF-8) encoded character sets, as they need no notion of how many byte long a character is, while others (e.g., strchr) depend on one character being encoded in a single char value and are of less use for UTF-8 (strchr still works fine if you just search for an ASCII character in a UTF-8 string). Other C functions are locale dependent and work in UTF-8 locales just as well: strcoll strxfrm Γενικώς γίνεται λίγο μύλος! Το ASCII table περιλαμβάνεται αυτούσιο μέσα στο UTF-8, στο low (ή high) byte του UTF-8, αν κάποιος χαρακτήρας έχει περισσότερα του 1ος bytes, ανάλογα την πλατφόρμα. Btw, τελικά κατάφερα να το κάνω να δουλεύει και με MinGW, ορίζοντας στο registry ως default codepage της γραμμής εντολών την 1253. Επίσης, δουλεύει και με 65001 εδώ στα XP. Αλήθεια, η 65001 είναι true UTF-8 κωδικοσελίδα ή είναι κουτσουρεμένη πάντα σε 1 byte? Ξέρει κανείς; Αύριο θα το τσεκάρω και σε Windows 7 κι αν δουλεύει κι εκεί, τότε θα αρχίζω να ψάχνομαι πιο επισταμένα και για UTF-8.
ΠάρηςΓ Δημοσ. 9 Ιουνίου 2011 Δημοσ. 9 Ιουνίου 2011 1253 δεν ειναι unicode 65001 ειναι UTF8 Εγω τωρα που εκανα μια δοκιμή μια χαρά παιζουν τα ελληνικά σε UTF8.. windose 7... 1)To αρχειο το σωζουμε ως UTF-8 ,στο visual studio επιλεγουμε save as και μετα στο save το βελακι save with encoding (κατι τετοιο) 2) SetConsoleCP(65001); SetConsoleOutputCP(65001); printf("ΔΟΚΙΜΗ μπλα μπλα"); 3)Τρεχουμε το προγραμμα και επιλεγουμε καποιο TT font και οχι τα Raster default.. 4)Το ξανατρεχουμε και θα παιζει μια χαρά.
Directx Δημοσ. 9 Ιουνίου 2011 Δημοσ. 9 Ιουνίου 2011 Ο ΠάρηςΓ έχει δίκιο, το CP 65001 δουλεύει, οπότε το θέμα για εμένα ήταν γιατί δεν δούλευε σωστά στον C++ Builder που χρησιμοποιώ. Πριν ξεκινήσω, κρατώ την εύστοχη παρατήρηση του migf1: Γενικώς γίνεται λίγο μύλος! ..Πράγματι, διότι από εκεί και πέρα το θέμα υποστήριξης UTF-8 μετατρέπεται σε υπόθεση του compiler και όσον αφορά τον C++ Builder 2009 που χρησιμοποιώ η συνταγή για να γράψει UTF-8 (65001) στην κονσόλα είναι: Project->Options->Advance->Code page = 65001 ώστε ο compiler να παράγει UTF8 έξοδο στο εκτελέσιμο. Δεξί κλικ στον Editor όπου υπάρχει ο πηγαίος κώδικας μας και επιλογή του UTF8 ως File Format, ώστε ο κώδικας να αποθηκευθεί σε μορφή UTF8. Ορισμός των String σε ASCII C μορφή (char κτλ) αντί wide-char (wchar_t, L’ ’ κτλ) διότι διαφορετικά το string θα κωδικοποιηθεί ως Unicode μεν αλλά όχι μορφής UTF-8 οπότε δεν θα εκτυπωθεί επιτυχώς στην κονσόλα μέσο των stdio.h εντολών. Ανάλογη ρύθμιση της Κονσόλας (CHCP, True Type font). Ειδικά το 3ο βήμα είναι πολύ σημαντικό διότι αν δεν ληφθεί υπόψη τότε όλα τα wide string της εφαρμογής μεταφράζονται μεν σε Unicode αλλά όχι μορφής UTF-8 οπότε μένεις με την εντύπωση ότι το CP 65001 της κονσόλας δεν δουλεύει καθώς νομίζεις ότι ο C++ Builder εφόσον δηλώνεις Unicode support θα χρησιμοποιήσει αυτόματα το UTF-8 format πράγμα που δεν ισχύει. Από περιέργεια είδα ότι και τα .NET C# προγράμματα κονσόλας κωδικοποιούν το Unicode σε μη UTF-8 μορφή (όπως και ο C++ Builder) αλλά σε αντίθεση με τον C++ Builder εκτυπώνουν σωστά στην κονσόλα προφανώς διότι χρησιμοποιούν το Unicode Console API. Σε κάθε άλλη περίπτωση (επιθυμία χρήσης wchar_t κτλ) η χρήση της WriteConsoleW φαίνεται μονόδρομος (σε C++ Builder πάντα) καθώς η ανάλογη ρουτίνα (wprintf) του stdio δεν επιστρέφει τα αναμενόμενα ανεξαρτήτως ρυθμίσεως Unicode code-page (η εκτύπωση μέσο του C RTL γίνεται δια του WriteFile και διάφορων κλήσεων σε char-conversions αντί του Console API το οποίο τα καταφέρνει πολύ καλύτερα). Σε άλλους μεταφραστές τα πράματα μπορεί να είναι διαφορετικά.
ΠάρηςΓ Δημοσ. 9 Ιουνίου 2011 Δημοσ. 9 Ιουνίου 2011 Gia utf-16 νομιζω πως ειναι πιο δυσκολα τα πραγματα... Γιατι λεει available for managed applications only..
migf1 Δημοσ. 9 Ιουνίου 2011 Μέλος Δημοσ. 9 Ιουνίου 2011 Καλησπέρα παιδιά, καταρχήν ευχαριστώ για το ενδιαφέρον που δείχνετε! Με τα 8-μπιτα charsets πιστεύω τελειώσαμε, αφού μια χαρά δουλεύει και στην κονσόλα των Windows 7 η 1253. Και μάλιστα με Pelles-C του είναι αδιάφορο αν ο πηγαίος κώδικας σωθεί και γίνει compile ως UTF-8, αντίθετα με τον GCC που απαιτεί ο πηγαίος κώδικας να σωθεί ως ANSI πριν γίνει compile για να δουλέψει. Μένει μόνο να τεστάρει κάποιος και σε περιβάλλον Posix με locale "el_GR". Με το UTF όμως τα πράγματα δεν φαίνονται ευοίωνα. Καταρχήν η 65001 δεν σετάρεται μέσα από τον κώδικα εδώ στα 7αρια, ενώ στα XP γινόταν (το locale string στον MinGW είναι "Greek_Greece.65001" ή σκέτο ".65001"). Αλλά και στα XP είχε πρόβλημα τελικά, αφού το LC_CTYPE το άφηνε ως "C", παρόλο που όλα τα υπόλοιπα LC_ τα σέταρε ως UTF-8. Θεωρητικά αν ο κώδικας δουλεύει αποκλειστικά με wchar_t και τις συναφείς συναρτήσεις, του είναι αδιάφορο σε τι encoding είναι οι χαρακτήρες. Επειδή όμως τα τερματικά δεν είναι όλα ικανά να διαβάζουν/τυπώνουν όλα τα encodings, είναι καλό να ξέρουμε σε τι encoding διαβάζουμε, να το μετατρέπουμε σε wchar_t για να το διαχειριστούμε και να το μετατρέπουμε ξανά πριν το τυπώσουμε (με τις σχετικές multi-byte συναρτήσεις της C). Το wchar_t είναι εγγυημένα από το στάνταρ fixed-size στα 4 bytes, οπότε διευκολύνει πάρα πολύ όταν δουλεύουμε με UTF-32 που είναι επίσης fixed-size στα 4 bytes ανά χαρακτήρα. Έχουν όμως πολύ μεγάλο penalty σε μνήμη (και σε ταχύτητα). Όλα αυτά όμως εκτός από τη γενικότερη βαβούρα προϋποθέτουν και εξοικείωση με τις wchar_t συναρτήσεις και τις παραμέτρους τους, κάτι που προσωπικά ήθελα και θέλω να αποφύγω. Όπως ανάφερα και χτες, το UTF-8 που έχει χαρακτήρες μεταβλητού μήκους, από 1 έως 4 bytes, είναι το μόνο από τα UTF που παρέχει πλήρη συμβατότητα με το ASCII, μιας και το περιέχει αυτούσιο στο 1ο του byte. Παραθέτω και ένα σχετικό κειμενάκι από το Wiki... Unicode can be implemented by different character encodings. The most commonly used encodings are UTF-8 (which uses one byte for any ASCII characters, which have the same code values in both UTF-8 and ASCII encoding, and up to four bytes for other characters), the now-obsolete UCS-2 (which uses two bytes for each character but cannot encode every character in the current Unicode standard), and UTF-16 (which extends UCS-2 to handle code points beyond the scope of UCS-2). Για αυτό τον λόγο από ότι έχω καταλάβει δουλεύουν και οι περισσότερες από τις στάνταρ συναρτήσεις διαχείρισης strings. Βέβαια έχω ακόμα ερωτηματικά, όπως για παράδειγμα: τα περιεχόμενα του ASCII πάνω από 127 τα ορίζει το πρότυπο του UTF-8; Κι αν ναι, ποια είναι; Αν τα ορίζει το πρότυπο του UTF-8 μάλλον δεν θα περιλαμβάνουν Ελληνικά, οπότε αναγκαστικά θα χρειαστεί πάλι η χρήση wchar_t και μετατροπές μεταξύ wide και multi-byte. Αν από την άλλη μεριά αν υπάρχει κάποιο στάνταρ συνεργασίας μεταξύ UTF-8 και τρέχοντος ANSI encoding, ώστε για παράδειγμα οι χαρακτήρες 127-255 να ορίζονται από κάποιο custom defined ANSI encoding ακόμα κι αν δουλεύουμε με UTF-8, τότε ο κώδικας που έχω γράψει στο 1ο ποστ θα μπορεί να δουλεύει αυτούσιος, χωρίς φυσικά να εκμεταλλεύεται τυχόν UTF-8 χαρακτήρες μήκους μεγαλύτερου του 1ος byte. Μπακαλοδουλειά προφανώς, αλλά τουλάχιστον δεν θα γράφει κινέζικα στην κονσόλα όταν την έχεις γυρισμένη σε 65001. Το UTF-8 είναι το ΜΟΝΑΔΙΚΟ UTF που παράσχει πλήρη συμβατότητα με το ASCII table! Θα το ψάξω πιο επισταμένα τώρα που τελειώσαμε με τα ANSI encodings, και θα επανέλθω με νεότερα (αν βγάλω καμιλα άκρη δλδ ). ΥΓ1. Η χρήση συναρτήσεων από το Windows API είναι no-no στην περίπτωσή μας, γιατί υποτίθεται πως τον κώδικα τον γράφουμε σε στάνταρ C για να γίνεται compile σε πολλές πλατφόρμες. ΥΓ2. Διαβάζω πως για UTF, ο GCC απαιτεί ο πηγαίος κώδικας να είναι αποθηκευμένος ΧΩΡΙΣ BOM, σε αντίθεση με το Visual Studio που απαιτεί να είναι αποθηκευμένος ΜΕ BOM (κλάφτα Χαράλαμπε δλδ).
ΠάρηςΓ Δημοσ. 9 Ιουνίου 2011 Δημοσ. 9 Ιουνίου 2011 Το UNICODE εχει μοναδικό κωδικό για κάθε γράμμα... UTF-8 UTF-16 UTF-32 ειναι απλα κωδικοποιήσεις αλλα στην ουσια τον ιδιο κωδικό συμβολίζουν... Για το UTF16 θυμαμαι οταν ξεφύγει απο καποιο οριο υπάρχει ενα reserved space καπως που δηλώνει οτι θελει και αλλο byte.. http://www.unicode.org/charts/ Δε γινεται να αποφυγεις τελειως τα WINAPI . Εξαλλου η windose console δεν εχει ΑΝSI escape codes.. Απλα ορισε με ifdef καπως για συμβατότητα..
migf1 Δημοσ. 9 Ιουνίου 2011 Μέλος Δημοσ. 9 Ιουνίου 2011 Το UNICODE εχει μοναδικό κωδικό για κάθε γράμμα... UTF-8 UTF-16 UTF-32 ειναι απλα κωδικοποιήσεις αλλα στην ουσια τον ιδιο κωδικό συμβολίζουν... Για το UTF16 θυμαμαι οταν ξεφύγει απο καποιο οριο υπάρχει ενα reserved space καπως που δηλώνει οτι θελει και αλλο byte.. http://www.unicode.org/charts/ Δε γινεται να αποφυγεις τελειως τα WINAPI . Εξαλλου η windose console δεν εχει ΑΝSI escape codes.. Απλα ορισε με ifdef καπως για συμβατότητα.. Thanks για το link! Μοναδικό κωδικό έχει το κάθε γράμμα, αλλά δεν αποθηκεύονται όλα τα γράμματα σε ίδιο αριθμό bytes στη μνήμη σε όλα τα UTF encodings. Στο UTF-32 όλα τα γράμματα έχουν fixed-size (32 bits/4 bytes) αλλά στο UTF-8 τα γράμματα είναι variable-sized από 1 έως 4 bytes. Variable sized είναι και το UTF-16 νομίζω. http://en.wikipedia.org/wiki/Character_encoding#Unicode_encoding_model (δες εκεί που λέει CEF). Πάντως αν το κατάλαβα σωστά, σύμφωνα με το link που μου έδωσες το θέμα επανέρχεται στο πως θα ορίσουμε μέσα στον κώδικα το UTF-8 script που χρειαζόμαστε. Σε περιβάλλον POSIX είναι προφανές: "el_GR.UTF-8", αλλά το 65001 σε ποιο UTF-8 scipt αντιστοιχεί, ξέρουμε; Όσο πάει γίνεται και χειρότερο, θα τα παρατήσω μου φαίνεται και θα μείνω στην 1253 να τελειώνω
Directx Δημοσ. 9 Ιουνίου 2011 Δημοσ. 9 Ιουνίου 2011 Από όσο γνωρίζω το Unicode προσφέρει συμβατότητα στο BASIC ASCII (ή 7-BIT ASCII) δηλαδή μέχρι το 127 από εκεί και πέρα όσον αφορά το EXTENDED ASCII (8-BIT ASCII) τα πράματα αλλάζουν, για περισσότερα μπορείς να δεις εδώ όπου προσφέρει το σύνολο της κωδικοποίησης κάθε χαρακτήρα σε Unicode, UTF-8, SJIS και HTML. Για παράδειγμα η κωδικοποίηση του Ελληνικού κεφαλαίου Ε (δίχως τόνο) σε Unicode ορίζεται ως 0x0395 ενώ στο UTF-8 ορίζεται ως 0xCE95.
migf1 Δημοσ. 9 Ιουνίου 2011 Μέλος Δημοσ. 9 Ιουνίου 2011 Δυστυχώς μόλις ανακάλυψα αυτό που λες DirectX εδώ: http://en.wikipedia.org/wiki/UTF-8 (btw, good read !) Οπότε, ζήσε Μάη μου να φας τριφύλλι! Μάλλον είναι αναπόφευκτη η μετατροπή σε wchar_t KAI για τη διαχείριση και του UTF-8 Δεν με βλέπω να την παλεύω αν είναι έτσι, μια χαρά είναι και η 1253
Προτεινόμενες αναρτήσεις
Αρχειοθετημένο
Αυτό το θέμα έχει αρχειοθετηθεί και είναι κλειστό για περαιτέρω απαντήσεις.