Προς το περιεχόμενο

Ελληνικά στη κονσόλα των Windows, με στάνταρ C


migf1

Προτεινόμενες αναρτήσεις

Αρχικά υπολόγιζα να ποστάρω το παρακάτω ως αναλυτική απάντηση σε ένα άλλο νήμα, όπου ο φίλος cvb ρώτησε αν είναι μονδρομος το win32 api προκειμένου να γράφουμε και να διαβάζουμε ελληνικά στη κονσόλα των Windows.

 

Σκέφτηκα όμως πως θα είναι πιο χρήσιμο ως ξεχωριστό νήμα.

 

Πριν κατεβάσετε οτιδήποτε προτείνω στο νήμα και το έχω μαρκάρει με κόκκινο αστερίσκο, διαβάστε πρώτα την προειδοποίηση στο τέλος του ποστ.

 

 

ΕΛΛΗΝΙΚΑ ΜΕ ΣΤΑΝΤΑΡ C ΣΤΗΝ ΚΟΝΣΟΛΑ ΤΩΝ WINDOWS (δοκιμασμένα σε Win 8.1 Pro)

 

Η διαχείριση ελληνικών μέσα από στάνταρ C στην κονσόλα των Windows, δυστυχώς είναι πονεμένη ιστορία. Θα προσπαθήσω να εξηγήσω ΕΝΑΝ τρόπο πως μπορεί να γίνει χωρίς χρήση του <wchar.h> (και προφανώς χωρίς χρήση ούτε του win32 api), χρησιμοποιώντας ως compiler τον mingw32-gcc, είτε απο τη γραμμή εντολών με Notepad++, είτε με το ide Code::Blocks.

 

Ο installer του mingw32 tool-chain βρίσκεται εδώ: http://sourceforge.net/projects/mingw/files/Installer/ (*)

 

Προσωπικά το στήνω αυτόνομα στη γραμμή εντολών, επιλέγοντας υποστήριξη c, c++, & objective-c στον installer, και κατόπιν το χρησιμοποιώ είτε με το Notepad++, είτε με το Code::Blocks (*) ... δείτε παρακάτω ποιο αρχείο να κατεβάσετε).

 

Για να το χρησιμοποιήσετε με το Notepad++ ως IDE (αντί για απλό editor), δείτε οδηγίες εδώ: http://www.insomnia.gr/topic/450299-notepad-plugins-mingw-ide/ , αν και αναφέρονται σε παλαιότερες εκδόσεις του mingw32 installer. Στον καινούριο, μπορείτε να επιλέξετε (εκτός από τους compilers) είτε το base-msys πακέτο, είτε το full-development-msys πακέτο.

 

Για το Code::Blocks, από τη στιγμή που το mingw32 tool-chain είναι ήδη εγκατεστημένο στο σύστημά σας, κατεβάζετε

  • είτε το: codeblocks-13.12-nosetup.exe
  • είτε το codeblocks-13.12-setup.exe
(από το λινκ που έδωσα παραπάνω)

 

Όταν τρέξει θα βρει μόνο του πως υπάρχει ο gcc στο σύστημά... τον διαλέγετε όταν σας ρωτήσει το code::blocks και είστε ΟΚ.

 

Τα υπόλοιπα .exe που βλέπετε στο παραπάνω λινκ, περιλαμβάνουν μαζί με το IDE και το TDM GCC toolchain, το οποίο είναι ένα πακετάρισμα με κάποια στοιχεία παρμένα από το mingw32 προτζεκτ και κάποια άλλα από το mingw-w64 προτζεκτ. Πιθανότατα οι οδηγίες που θα δώσω παρακάτω για τα ελληνικά να δουλεύουν και με το TDM GCC toolchain, αλλά εγώ τις έχω δοκιμάσει μονάχα με το καθαρό mingw32 (στον παλιό δίσκο με τα Windows XP, έχω στημένο και το mingw-w64 toolchain, παράλληλα με το ming32, αλλά τώρα στον δίσκο με τα Windows 8.1 έχω βάλει μονάχα το mingw32 και δεν θυμάμαι απ' έξω τι γίνεται με τα ελληνικά στο mingw-w64).

 

 

Μικρός Πρόλογος

 

Το πρόβλημα έχει να κάνει με το ότι η κωδικοσελίδα (codepage) (και η γραμματοσειρά (font)) της κονσόλας των Windows δεν συμφωνεί με την κωδικοσελίδα των εκτελέσιμων που βγάζουν οι compilers.

 

Επίσης, χωρίς ειδική μέριμνα, η κωδικοσελίδα των εκτελέσιμων που βγάζουν οι compilers συνήθως (αλλά όχι πάντα) εξαρτάται από την κωδικοσελίδα στην οποία είναι γραμμένα τα πηγαία αρχεία του προγράμματος (δλδ ως επί το πλείστον τα .c και .h).

 

Αυτό που βασικά θέλουμε είναι, η κωδικοσελίδα της κονσόλας των Windows να είναι ίδια με την κωδικοσελίδα που χρησιμοποιεί το compiled εκτελέσιμο (και παράλληλα, η γραμματοσειρά της κονσόλας να υποστηριζει όλα τα σύμβολα της επιλεγμένης κωδικοσελίδας).

 

 

Ελέγχοντας τις Κωδικοσελίδες Πηγαίων & Εκτελέσιμου με τον GCC

 

Ο gnu-gcc (άρα λογικά και τα περισσότερα ports του, αν όχι όλα) δέχεται στη γραμμή εντολών του 2 options με τα οποία του λέμε σε ποια κωδικοσελίδα είναι γραμμένα τα πηγαία μας αρχεία, και ποια κωδικοσελίδα θέλουμε να χρησιμοποιεί το εκτελέσιμο.

 

Για τα πηγαία αρχεία, είναι το option -finput-charset=X και για τα εκτελέσιμα είναι το -fexec-charset=X (όπου X βάζουμε την επιθυμητή κωδικοσελίδα, σύμφωνα με τη βιβλιοθήκη gnu iconv).

Αν δεν υπάρχουν αυτά τα options στη γραμμή εντολών του, ο gcc κάνει default σε κωδικοσελίδα "utf-8" (αυτό ΔΕΝ ισχύει όμως στον mingw32-gcc).

 

Άρα αν γράψουμε πηγαίο κώδικα ας πούμε σε κωδικωσελίδα utf-8 αλλά θέλουμε το εκτελέσιμο να λειτουργεί σε κωδικοσελίδα 737, δίνουμε στη γραμμή εντολών:

gcc -finput-charset=utf-8 -fexec-charset=cp737 myprog.c -o myprog.exe

Βρίσκοντας την Κωδικοσελίδα της Κονσόλας των Windows

 

Για να βρούμε σε ποια κωδικοσελίδα είναι γυρισμένη η κονσόλα των Windows, ανοίγουμε ένα παράθυρο γραμμής εντολών (cmd.exe), γράφουμε: chcp και θα μας πει...

 

Εικόνα:

 

PUlO4VS.png?1

 

 

Στην παραπάνω εικόνα η ενεργή κωδικοσελίδα της κονσόλας είναι η 737, δηλαδή η: cp737 σύμφωνα με την ορολογία της βιβλιοθήκης gnu-libiconv (έχω δώσει σχετικό λινκ παραπάνω).

 

Ξέρουμε λοιπόν, πως θέλουμε να κάνουμε compile με:

gcc -fexec-charset=cp737 ...

Ορίζοντας την Κωδικοσελίδα Πηγαίων Αρχείων

 

Το πως καθορίζουμε σε ποια κωδικοσελίδα θα σώζουμε τα πηγαία μας αρχεία διαφέρει από ide σε ide κι από editor σε editor.

 

Στο Notepad++ είναι στο μενού: Encoding ...

Εικόνα:

 

AFYwDfo.png?1

 

 

Στο Code::Blocks 13.12 είναι στο μενού: Edit -> File encoding...

Εικόνα:

ENiOurD.png?1

 

Μπορείτε να πειραματιστείτε με διάφορες κωδικοσελίδες στα παραπάνω μενού, αλλά σημειώστε πως ΔΕΝ είναι εφικτές όλες οι μετατροπές από την μια κωδικοσελίδα στην άλλη, με τη βιβλιοθήκη gnu libiconv. Όταν η μετατροπή από την κωδικοσελίδα πηγαίων στην κωδικοσελίδα εκτελέσιμου αποτύχει, ο gcc βγάζει σχετικό λάθος κατά το compilation.

 

Σε γενικές γραμμές μπορείτε να ορίσετε την κωδικοσελίδα πηγαίων σε UTF8 (αν έχετε επιλογή, δοκιμάστε πρώτα χωρίς BOM).

 

 

Τελική Γραμμή Εντολών Για Compilation

 

Υποθέτοντας τώρα πως σύμφωνα με όλα τα παραπάνω έχουμε γράψει ένα hello.c που τυπώνει "Γεια σου κόσμε" στην κονσόλα, καταλήγουμε ότι το τελικό compilation το κάνουμε με την παρακάτω εντολή:

gcc -finput-charset=utf-8 -fexec-charset=cp737 hello.c -o hello.exe
Αν η κωδικοσελίδα της κονσόλας σας είναι όντως η 737 (που είναι και το πλέον πιθανό) τότε θα δείτε να τυπώνονται κανονικά τα ελληνικά μηνύματα των προγραμμάτων σας.

 

Για να προσθέσουμε τα παραπάνω compilation options στο Code:Blocks, αφού έχουμε δημιουργήσει πρώτα το project, πάμε στο μενού Project -> Build options... και στο παράθυρο που ανοίγει γράφουμε αυτά που δείχνει η παρακάτω εικόνα (σε spoiler), εκτός από το -std=c99 (αυτό είναι για να ενεργοποιηθούν οι βελτιώσεις της 99):

 

Εικόνα:

 

nUXq9uQ.png?1

 

 

Προσέξτε πως στο δέντρο αριστερά ΔΕΝ είναι επιλεγμένη ούτε η Debug, ούτε η Release έκδοση του compilation. Είναι επιλεγμένη ή ρίζα του δέντρου (το hello) ώστε αυτά τα options να λειτουργούν είτε κάνουμε Debug είτε Release compilation.

 

 

Άλλα IDEs (δλδ πλην του Code::Blocks)

 

Δυστυχώς με Pelles-C και Orwell Dev-C++ δεν δουλεύουν τα παραπάνω. Στη μεν Pelles-C επειδή δεν μας αφήνει να ορίσουμε την κωδικοσελίδα του εκτελέσιμου (δεν υπάρχει δηλαδή option αντίστοιχο του -fexec-charset, ή δεν το έχω βρει ακόμα), στο δε Orwell Dev-C++ (που χρησιμοποιεί gcc) επειδή το IDE δεν μας αφήνει να αλλάξουμε την κωδικοποίηση των πηγαίων αρχείων (ούτε καν να τη δούμε, αν κι έχω πάνω από χρόνο που τσεκάρισα για τελευταία φορά).

 

To Visual Studio ξέρω πως μας αφήνει να αλλάξουμε την κωδικοσελίδα των πηγαίων αρχείων μας, αλλά επειδή δεν το έχω εγκατεστημένο τώρα, ούτε θυμάμαι από που το αλλάζουμε, ούτε ξέρω αν ο compiler του παρέχει options αντίστοιχα των -finput-charset & -fexec-charset). Ελπίζω να συμπληρώσει αυτές τις πληροφορίες κάποιος που είναι εξοικειωμένος με το VS.

 

Το ίδιο ελπίζω και για άλλα IDEs που υποστηρίζουν C.

 

 

Αλλάζοντας τη Γραμματοσειρά (και την κωδικοσελίδα) της Κονσόλας

 

Η κωδικοσελίδα 737 της κονσόλας (και πιο συγκεκριμένα OEM 737 στην ορολογία των Windows) είναι από την εποχή του DOS, έχει υποστήριξη ελληνικών και δουλεύει με τα default bitmap fonts της κονσόλας (τα λέει: raster).

 

Πιο ανεπτυγμένες κωδικοσελίδες (όπως π.χ. οι UTF, αλλά και μερικές ANSI) χρησιμοποιούν σύμβολα που δεν υπάρχουν στη γραμματοσειρά raster, ή που υπάρχουν σε διαφορετικές θέσεις. Αν λοιπόν γυρίσουμε την κονσόλα σε μια τέτοια κωδικοσελίδα και ταυτόχρονα ΔΕΝ αλλάξουμε τη γραμματοσειρά της κονσόλας, τότε είναι πολύ πιθανό όλα ή τα περισσότερα ελληνικά να εμφανίζονται ως... "κινέζικα".

 

Όλες οι κωδικοσελίδες που υποστηρίζονται στη κονσόλα των Windows, αναφέρονται εδώ: https://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx

 

Νομίζω πως χρειάζεται ειδική μνεία για την κωδικοσελίδα 65001, που στην παραπάνω σελίδα της Microsoft αναγράφεται ως UTF-8. Πρόκειται για υποσύνολο του πραγματικού UTF8. Το πραγματικό UTF8 encoding χρησιμοποιεί από 1 έως 4 bytes, ενώ η κονσόλα των Windows περιορίζεται στα 2 bytes (με μια μικρή επιφύλαξη αυτό το τελευταίο). Αν επιχειρήσετε να τυπώσετε μέσω -fexec-charset=utf-8 στη κονσόλα των Windows, προφανώς με κατάλληλη γραμματοσειρά και κωδικοσελίδα γυρισμένη σε 65001, έχετέ το υπόψιν (γενικώς δεν προτείνεται να το κάνετε).

 

Τα Windows 7/8, εκτός από την bitmap Raster, παρέχουν 2 ακόμα γραμματοσειρές για την κονσόλα, οι οποίες είναι TrueType και πολύ πιο εμπλουτισμένες σε σύμβολα: την "Lucida Console" και την "Consolas". Νομίζω πως η Consolas είναι η πιο εμπλουτισμένη σε σύμβολα από τις 3. Είναι επίσης συμβατές με την raster, οπότε ουσιαστικά δεν υπάρχει λόγος να έχουμε την κονσόλα με Raster γραμματοσειρά.

 

Η εικόνα που ακολουθεί δείχνει πως μπορούμε να αλλάξουμε γραμματοσειρά σε ένα παράθυρο κονσόλας (τις αλλαγές τις "κρατάνε" κατόπιν τα Windows για το συγκεκριμένο παράθυρο/εκτελέσιμο).

 

Εικόνα:

CpknbGI.png?1

 

Τέλος, για να αλλάξετε την τρέχουσα κωδικοσελίδα της κονσόλας, γράφετε:

chcp X
(όπου Χ, ένας από τους identifiers που καταλαβαίνει η κονσόλα, στο λινκ που έδωσα παραπάνω).

 

Αν θέλετε να το κάνετε μέσα από κώδικα (προφανώς χωρίς να χρησιμοποιήσετε το win32 api) μπορείτε να γράψετε:

system( "chcp X" ); // όπου Χ το id της κωδικοσελίδας
αλλά σημειώστε πως πρέπει να είναι αλλαγμένο και το παράθυρο του εκτελέσιμου σε συμβατή γραμματοσειρά (αλλιώς... "κινέζικα" πάλι :P)

 

 

(*) ΠΡΟΣΟΧΗ !!!

 

Πρόσφατα το SourceForge άρχισε να κάνει wrap τους installers των κατασκευαστών με δικό του installer, ο οποίος εγκαθιστά adware/crapware. Ανάμεσα στα θύματα αυτής της πρακτικής του SF είναι πολύ γνωστά πρότζεκτ, όπως το Gimp, το VLC και το nMap (τα οποία όπως ήταν λογικό εγκατέλειψαν το SF). Για αυτό, ΜΗΝ ΠΑΤΑΤΕ ΣΤΑ Download buttons του SF... αντί αυτού, να πηγαίνετε μέσα στα Files του προτζεκτ και να πατάτε πάνω στο όνομα του αρχείου που θέλετε να κατεβάσετε, στη λίστα αρχείων. Ακόμα κι αυτό όμως δεν σας εξασφαλίζει 100%. Για να είστε 100% σίγουροι, να κατεβάζετε από τις επίσημες σελίδες των κατασκευαστών.

  • Like 4
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • 1 μήνα μετά...
Δημοσ. (επεξεργασμένο)
...

 

Άλλα IDEs (δλδ πλην του Code::Blocks)

 

Δυστυχώς με Pelles-C και Orwell Dev-C++ δεν δουλεύουν τα παραπάνω. Στη μεν Pelles-C επειδή δεν μας αφήνει να ορίσουμε την κωδικοσελίδα του εκτελέσιμου (δεν υπάρχει δηλαδή option αντίστοιχο του -fexec-charset, ή δεν το έχω βρει ακόμα), στο δε Orwell Dev-C++ (που χρησιμοποιεί gcc) επειδή το IDE δεν μας αφήνει να αλλάξουμε την κωδικοποίηση των πηγαίων αρχείων (ούτε καν να τη δούμε, αν κι έχω πάνω από χρόνο που τσεκάρισα για τελευταία φορά)

....

 

Κατέβασα σήμερα την τελευταία έκδοση του Orwell Dev-C++ και φαίνεται πως τελικά αποθηκεύει τα πηγαία αρχεία σε cp1253 (ή σε iso-8859-7). Πιο συγκεκριμένα δοκίμασα επιτυχώς και με τα 2 αυτά charsets ως τιμές του -finput-charset  (και με mingw32 και με mingw-w64) αλλά για σιγουριά καλύτερα η cp1253.

 

Το παράθυρο γραμμής εντολών το έχω αφημένο στη default κωδικοσελίδα 737, με Raster font, οπότε το compilation γίνεται όπως δείχνει η παρακάτω εικόνα:

 

Εικόνα:

 

R8JGbsI.jpg

 

Έξοδος:

fbQ2rxF.jpg

 

 

 

Αν στην κονσόλα που ανοίγει & τρέχει το πρόγραμμα  ορίσω γραμματοσειρά Lucida Console ή Consolas, τότε θα μπορούσα να κάνω uncomment στον κώδικα τη γραμμή:  system( "chcp 1253" ); και να αλλάξω αντίστοιχα στη γραμμή εντολών του gcc την κωδικοσελίδα του παραγόμενου εκτελέσιμου, δηλαδή: -fexec-charset=cp1253

 

EDIT:

 

Σε cp1253 αποθηκεύει τελικά (δείτε τα 2 επόμενα μηνύματα του νήματος).

Επεξ/σία από migf1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

αποθηκεύει τα πηγαία αρχεία σε cp1253 (ή σε iso-8859-7). Πιο συγκεκριμένα δοκίμασα επιτυχώς και με τα 2 αυτά charsets ως τιμές του -finput-charset  (και με mingw32 και με mingw-w64) αλλά για σιγουριά καλύτερα η cp1253.

Βάλε στην puts να εμφανίσει ένα κεφαλαίο άλφα με τόνο Ά και άσε τις ρυθμίσεις του mingw έτσι που τις έχεις -finput-charset=cp1253. Αν αντί για Ά εμφανιστεί κάτι που να μοιάζει με μονό εισαγωγικό ' τότε το σώζει σε ISO.

 

(Αν χρησιμοποιούσες iso στον mingw για input-charset, πάλι θα δοκίμαζες με το Ά. Αν εμφανιζόταν το σύμβολο της παραγράφου ¶ θα σήμαινε ότι το σώζει σε windows-1253).

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Σε cp1253 αποθηκεύει τελικά. Με Ά αποτυγχάνει η μετατροπή από iso-8859-7 σε cp737 (σταματάει το compilation).

Παράξενο. Δεν θα έπρεπε να σταματάει γιατί δεν υπάρχει κάποιος παράνομος χαρακτήρας. Απλά θα έπρεπε να μην εμφανίζεται "σωστά".

 

 

 

% cat > utf8.c << EOF

> #include <stdio.h>
> 
> int main(void)
> {
>       puts("Αυτό είναι ένα Ά");
>       return 0;
> }
> EOF

% cc -o utf8 utf8.c 
% ./a.out 
Αυτό είναι ένα Ά

% for i in windows-1253 iso8859-7; do
   iconv -f utf8 -t $i -o ${i}.c utf8.c                                            
   cc -Wall -finput-charset=${i} -o ${i} ${i}.c    
   ./${i} 
done
Αυτό είναι ένα Ά
Αυτό είναι ένα Ά
Όπως ήταν αναμενόμενο όλα παίζουν σωστά. Ας δοκιμάσουμε ανάποδα.

 

% cc -finput-charset=windows-1253 -o windows-1253 iso8859-7.c 
% cc -finput-charset=iso8859-7 -o iso8859-7 windows-1253.c 

% ./iso8859-7 
Αυτό είναι ένα ’
% ./windows-1253 
Αυτό είναι ένα ¶
Γράφουμε σε windows-1253 οπότε το Ά που γράψαμε βρίσκεται στη θέση 0xA2. Όταν μετά λέμε στον compiler να το ερμηνεύσει ως iso, στην θέση 0xA2 υπάρχει η απόστροφος οπότε εμφανίζει σωστά την απόστροφο. Ανάλογα και στην άλλη περίπτωση ερμηνεύουμε την θέση 0xB6 που είναι το σήμα της παραγράφου.

 

Φυσικά τα παραπάνω δεν τα έτρεξα σε orwell αλλά δεν καταλαβαίνω γιατί να συμπεριφέρεται διαφορετικά ο mingw.

 

 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Μάλλον δεν υπάρχει αντιστοίχιση στην 737 (ή δεν την "ξέρει" το iconv).

 

Πάντως δοκίμασα μόλις τώρα: -finput-charset=iso-8859-7 -fexec-charset=cp1253 με uncommented το system( "chcp 1253" ); και αλλαγμένο το console font σε Lucida Console, και βγάζει το Ά ως μονό εισαγωγικό.

 

Με -finput-charset=cp1253 -fexec-charset=iso-8859-7 βγάζει το Ά ως παράγραφο.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Μάλλον δεν υπάρχει αντιστοίχιση στην 737 (ή δεν την "ξέρει" το iconv).

 

Πάντως δοκίμασα μόλις τώρα: -finput-charset=iso-8859-7 -fexec-charset=cp1253 με uncommented το system( "chcp 1253" ); και αλλαγμένο το console font σε Lucida Console, και βγάζει το Ά ως μονό εισαγωγικό.

 

Με -finput-charset=cp1253 -fexec-charset=iso-8859-7 βγάζει το Ά ως παράγραφο.

Α σωστά. Δεν σκέφτηκα ότι γίνεται και δεύτερη μετάφραση (όπως στην δική μου περίπτωση γίνεται σε utf8 που είναι το exec-charset μου) οπότε εκείνη είναι η μετάφραση που αποτυγχάνει. Στην 737 δεν υπάρχει ούτε η απόστροφος ούτε η παράγραφος οπότε και κολλάει.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • 5 μήνες μετά...

Καλημέρα. Αν και έχει περάσει λίγος καιρός με το tdmgcc εμφανίζονται μια χαρά τα ελληνικά στην κονσόλα σε υπολογιστή με Windows 10, με το Visual Studio 2008 και το Pelles C δεν έχω ακόμα βρει άκρη. Ο κώδικας:

#include <stdio.h>

int main(void)
{
	printf("Κείμενο στα ελληνικά.\n");
	
	return 0;
}

αποθηκευμένος με το notepad σε κωδικοποίηση ansi και utf8 και μεταγλωττισμένος με τις εντολές:

gcc text_gr_ansi.c -o text_gr_ansi -w -finput-charset=iso8859-7 -fexec-charset=cp737 και
gcc text_gr_utf8.c -o text_gr_utf8 -w -finput-charset=utf-8 -fexec-charset=cp737

τα εμφανίζει σωστά.

 

Κατά την μεταγλώττιση του κώδικα με κωδικοποίηση unicode με την εντολή:

gcc text_gr_unicode.c -o text_gr_unicode -w -finput-charset=ucs-2le -fexec-charset=cp737

δεν ήταν δυνατόν να εμφανιστούν σωστά τα ελληνικά.

 

text_gr_ansi.png

 

text_gr_utf8.png

 

text_gr_unicode.png

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

 

Κατά την μεταγλώττιση του κώδικα με κωδικοποίηση unicode με την εντολή:

gcc text_gr_unicode.c -o text_gr_unicode -w -finput-charset=ucs-2le -fexec-charset=cp737

δεν ήταν δυνατόν να εμφανιστούν σωστά τα ελληνικά.

 

 

1. Δεν υπάρχει "κωδικοποίηση unicode".

2. Πού το ξέθαψες το UCS-2? Γιατί να θέλει κανείς να το χρησιμοποιήσει; Γιατί στη χειρότερη των περιπτώσεων όχι UTF-16;

3. Απ' ότι φαίνεται το πρόβλημά σου είναι απλά πως το input δεν είναι στο character set που δηλώνεις (όχι παράλογο, αν δηλώνεις UCS-2 -- πώς έκανες το encoding δηλαδή?).

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

αποθηκευμένος με το notepad σε κωδικοποίηση ansi και utf8 και μεταγλωττισμένος με τις εντολές:

gcc text_gr_ansi.c -o text_gr_ansi -w -finput-charset=iso8859-7 -fexec-charset=cp737 και
gcc text_gr_utf8.c -o text_gr_utf8 -w -finput-charset=utf-8 -fexec-charset=cp737
τα εμφανίζει σωστά.

 

Το τι θα δηλώσεις στον gcc, όπως σου είπε και ο defacer, εξαρτάται από τι χρησιμοποιεί το κείμενό σου. Αν το κείμενο το έχεις αποθηκευμένο σε utf-8 θα δηλώσεις αυτό αλλιώς εννοείται ότι δεν θα παίζει σωστά.

 

Κατά την μεταγλώττιση του κώδικα με κωδικοποίηση unicode με την εντολή:

gcc text_gr_unicode.c -o text_gr_unicode -w -finput-charset=ucs-2le -fexec-charset=cp737
δεν ήταν δυνατόν να εμφανιστούν σωστά τα ελληνικά.

 

Εφόσον τα άλλα παίζουν γιατί δεν χρησιμοποιείς κάποιο από εκείνα (πχ το utf-8) ? Επίσης το αρχείο text_gr_unicode με τι encoding είναι αποθηκευμένο ? Δηλώνεις ότι θέλεις να μετατραπεί από ucs-2le αλλά είναι όντως το αρχείο έτσι ? Αν μπορείς επισύναψε το εδώ να το δούμε (όχι επικόλληση του κειμένου αλλά επισύναψη ολόκληρου του αρχείου).

 

 

1. Δεν υπάρχει "κωδικοποίηση unicode".

+1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

offtopic

 

Σε Vb6 αυτές είναι οι ρουτίνες του Kernel για να κάνουν τις μετατροπές από και προς Wide Char.

Αν θέλουμε η codepage  του MultiByte να είναι η UTF8 τότε έχουμε αυτό: Const Utf8CodePage As Long = 65001

dwflags βάζουμε τιμή 0

Πρέπει να καλούμε δυο φορές για να εξάγουμε σε UTF-8. Η μία κάνει το λογαριασμό πόσα bytes θέλουμε και η δεύτερη μας τα δίνει!

Όταν διαβάζουμε πρέπει να ξέρουμε πόσα Wchars θα μας δώσει ο πίνακας εδώ με bytes 

WChars = MultiByteToWideChar(65001, 0, shortbuf(1), st, 0, 0)
getUniStringLineUtF8 = Space$(WChars)
MultiByteToWideChar 65001, 0, shortbuf(1), st, StrPtr(getUniStringLineUtF8), WChars

Όταν γράφουμε
iLen = WideCharToMultiByte(Utf8CodePage, 0, VarPtr(A(0)), CLng(UBound(A) - LBound(A) + 1) \ 2, 0, 0, 0, 0)
ReDim bbBuf(0 To iLen - 1) 
iLen = WideCharToMultiByte(Utf8CodePage, 0, VarPtr(A(0)), CLng(UBound(A) - LBound(A) + 1) \ 2, VarPtr(bbBuf(0)), iLen, 0, 0)

Το WideChar είναι UTF16LE

 

Private Declare Function WideCharToMultiByte Lib "kernel32" (ByVal codepage As Long, ByVal dwFlags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, ByVal lpDefaultChar As Long, ByVal lpUsedDefaultChar As Long) As Long

Private Declare Function MultiByteToWideChar& Lib "kernel32" (ByVal codepage&, ByVal dwFlags&, MultiBytes As Any, ByVal cBytes&, ByVal pWideChars&, ByVal cWideChars&)
 

 

Η ιδέα είναι να έχουμε όλα τα μηνύματα σε UTF8 σε ένα αρχείο και να τα φορτώνουμε από εκεί, και να τα μετατρέπουμε σε wchar. Αυτό που δεν ξέρω είναι που βρίσκονται αυτές οι ρουτίνες σε Linux! (αν χρειαστεί να κάνουμε κάτι από εκεί)

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Καλημέρα. Defacer, Imithee από το λίγο που κοίταξα μια σελίδα που λέει για το

ucs-2le που χρησιμοποιεί ο μεταγλωττιστής ( http://www.gnu.org/software/libiconv/ ) κατάλαβα πως αναφέρει την σύντμηση της ονομασίας του πρότυπου κωδικοποίησης ως παράμετρο που μπορεί να την χρησιμοποιήσει κανείς και που γράφοντας την στην κονσόλα και παιρνόντας την με τις υπόλοιπες σχετικές εντολές, πράγμα που έκανα, ο μεταγλωττιστής διαβάζει το αρχείο πηγαίου κώδικα, το οποίο πρέπει να είναι αποθηκευμένο στην ίδια κωδικοποίηση την οποία του περάστηκε στον μεταγλωττιστή από την κονσόλα πως έχει, προκειμένου να το μεταγλωττίσει και να παράγει ένα εκτελέσιμο που δουλεύει σωστά. Ένα ερώτημα είναι γιατί ο μεταγλωττιστής έκανε κατά την μετατροπή του ucs2-le σε UTF-8 λάθος εμφανίζοντας τα αποτελέσματα της 3ης εικόνας. Ευχαριστώ πολύ για την βοήθεια.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ναι, το ερώτημα είναι αν όντως είχες το αρχείο σε ucs2le. To ucs2 είναι πανάρχαιο και δεν το χρησιμοποιεί κανείς. Πόσο σίγουρος είσαι ότι όντως αυτό έχεις;

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Ένα ερώτημα είναι γιατί ο μεταγλωττιστής έκανε κατά την μετατροπή του ucs2-le σε UTF-8 λάθος εμφανίζοντας τα αποτελέσματα της 3ης εικόνας.

Πιθανώς γιατί το αρχείο δεν είχε κωδικοποίηση ucs2-le. Χωρίς να δούμε το αρχείο, μόνο υποθέσεις μπορούμε να κάνουμε.

 

To ucs2 είναι πανάρχαιο και δεν το χρησιμοποιεί κανείς.

Στην περίπτωση που μιλάμε για ένα .c αρχείο με αγγλικά + ελληνικά όπου δεν έχουμε surrogate pairs και λοιπά, δεν ισχύει ucs-2le == utf16-le ? Οπότε αν το αρχείο του ήταν utf16, η iconv θα έπρεπε να παίξει ακόμη και με ucs2.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Γεια. Σκέφτηκα ότι το πρόγραμμα μεταγλώττισης του tdmgcc λογικά θα δούλευε σωστά και με την τρίτη εντολή που του δόθηκε προκειμένου να μεταγλωττίσει το αρχείο με τον κώδικα το οποίο ήταν αποθηκευμένο με κωδικοποίηση ucs2-le. Αν ενδιαφέρεται κανείς μπορεί να το διαπιστώσει αν το κοιτάξει σε έναν υπολογιστή με προγράμματα Windows 10, notepad, cmd, tdmgcc32, notepad++. Τώρα ως προς το αν τίθεται θέμα για το αν το αρχείο κωδικοποίησης υπάρχει ή όχι στο tdmgcc λογικά υπάρχει στο πακέτο του με τα εκτελέσιμα, διαφορετικά ενδεχομένως ο μεταγλωττιστής να εμφάνιζε στην κονσόλα διαφορετικά και σχετικότερα μηνύματα λάθους. Πάντως σχετικά με το αποτέλεσμα των δυο πρώτων εντολών μεταγλώττισης του αρχείου πηγαίου κώδικα και σχετικά με την απεικόνιση ελληνικών από την εκτέλεση των παραγόμενων από τον μεταγλωττιστή εκτελέσιμων αρχείων από την κονσόλα των Windows 10 έχουν φτιάξει πολύ όμορφα, χρήσιμα και δύσκολα να κατασκευαστούν πράγματα. Ευχαριστώ για την βοήθεια.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...