Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Merkistöt - ikuinen ongelma

Sivun loppuun

jsbasic [21.02.2011 17:34:21]

#

Ohjelmani lukee tiedostosta tekstin ja tulostaa sen (siihen dossin näköiseen) konsoliin.

"...Sillä on yhteistä rajaa myös Venäjän kanssa..."

Sama vika Windowsin kontrolliin tulostettuna. Mitä noille kirjaimille on tarkkaan ottaen tapahtunut? Onko käynyt niin että jotain UTF-x ollaan luettu kuin ascii-tekstiä?

C++ -kielen standardikirjastossa on joku wifstream, wchar_t ja wcout, jotka käsittelevät unicodeja, mutta ne eivät poistaneet tätä ongelmaa:

wchar_t *file_content;
wifstream file_stream;
file_stream.open("fiwiki.xml");
file_content = new wchar_t[1000];
file_stream.read( file_content, (streamsize)1000);
wcout << file_content;

Kun laitoin...

setlocale(LC_CTYPE, "fin");

...merkit vaihtuivat hieman toisenlaisiksi, mutta ei vieläkään tuonut oikeita merkkejä.

Javassa merkistökoodaus määritellään muistaakseni tiedoston avaamisen yhteydessä, mutta C++:lle en löytänyt vastaavaa.

Metabolix [21.02.2011 19:39:08]

#

Windowsin komentorivistä ei tietääkseni saa kunnollista UTF-8-tukea ulos kirveelläkään. Teoriassa funktioilla SetConsoleCP ja SetConsoleOutputCP pitäisi pystyä vaikuttamaan asiaan, mutta vaikka CP_UTF8 (65001) näyttäisikin toimivan lukemisessa ihan hyvin, tulostus ei edelleenkään toimi.

Itse pääsin jonkinlaisiin tuloksiin wchar_t:llä ja pitkän etsinnän tuloksena löytyneellä setlocale-magialla. Tulostuva merkistö on kuitenkin rajallinen, loput merkit kai jäävät tulostumatta.

#ifdef _WIN32
	setlocale(LC_ALL, ".OCP");
	setlocale(LC_CTYPE, ".OCP");
#endif
std::wcout << L"Tämähän toimii!";

Käytin tiedoston lukemiseen tavallista ifstreamia ja C:n mbstowcs-funktiota, koska silloinen MinGW:n versio ei tukenut w-streameja. Kokeile sinä niillä ja kerro, miltä nykyään näyttää. :)

jsbasic [21.02.2011 20:42:36]

#

Kyllä sain ääkköset näkymään dos-laatikossa esittämälläsi koodilla. (MinGW 4.5.2.)

XYZÅÄÖxyzåäö

Tuon fiwiki.xml tiedoston lukeminen tosin on ihan toinen ongelma, joka ei taida onnistua C++ standardikirjastoilla ollenkaan. Ehkä se on UTF-x tai ehkä ISO-xxxx-x, tai jotain...?

http://stackoverflow.com/questions/1274910/does-wifstream-support-different-encodings

Grez [21.02.2011 21:27:35]

#

Kyllä tuolla ainakin väitetään että pitäisi unicoden puskeminen onnistua konsoliin
http://xfgr.com/?u­=pz1z8ocodeprojectb0iczvKBczvcppczvunicode_conso­le_outputz6ax

jsbasic [21.02.2011 22:21:03]

#

Ehkä tällä MultiByteToWideChar:lla voi muuntaa alussa mainitsemani "myös Venäjän" -tekstiä unicodeksi.

http://msdn.microsoft.com/en-us/library/dd319072(v=vs.85).aspx

eq [21.02.2011 23:00:19]

#

jsbasic kirjoitti:

Ohjelmani lukee tiedostosta tekstin ja tulostaa sen (siihen dossin näköiseen) konsoliin.

"...Sillä on yhteistä rajaa myös Venäjän kanssa..."

Sama vika Windowsin kontrolliin tulostettuna. Mitä noille kirjaimille on tarkkaan ottaen tapahtunut? Onko käynyt niin että jotain UTF-x ollaan luettu kuin ascii-tekstiä?

Melkein (no, ei ihan kuitenkaan).

Tekstistä on helppo nähdä, että (sikäli kun vähäinen osaamiseni Windows-puolella ei johda tässä harhaan, niin) lähdemateriaali on ollut UTF-8:aa; ASCII-merkit näkyvät oikein, mutta ASCIIn ulkopuoliset merkit, kuten 'ä' ja 'ö' näkyvät paitsi väärin, myös kahtena merkkinä; tämä johtuu siitä, että UTF-8-muodossa (mm.) nämä kirjaimet tallennetaan koodiparina, eli kahtena tavuna.

Tiedoston lukemisessa ei kuitenkaan tapahdu mitään virheitä, sillä ainoa muunnos mitä (noin ymmärtääkseni) Windows-puolella tekstimuotoisille virroille tehdään, on rivinvaihtojen muunnokset; ja ne tapahtuvat turvallisesti ASCII-alueella eivätkä häiritse UTF-8-koodimerkkejä. Virheelliseltä näyttävä tulostus aiheutuukin täysin tulostusvaiheessa: ohjelma 'kirjoittaa' ulos-virtaan UTF-8:aa, mutta konsoli luulee saavansa joko latin1:ä (ISO-8859-1) tai Windows-1252:a (jälkimmäinen todennäköinen toki, Windowsista kun on kyse; tässä tapauksessa eroa ei kuitenkaan synny) - ja näyttää UTF-8-koodimerkit väärin.

Windows-konsolin saattaminen toimimaan oikein UTF-8:n kanssa on vaikeaa - jollei mahdotonta. Itse jättäisin haasteen väliin, ellei kyse ole työstä ja maksavan asiakkaan toiveesta: Windows-käyttäjät noin yleisesti eivät halua konsoli-ikkunoita käyttää, joten siltäkin kantilta ponnistelu on turhaa.

Jos haluat taas harjoitella C++-taitoja tekstipohjaisilla ohjelmilla, mutta et asentaa siihen soveltuvia käyttöjärjestelmiä (siis sellaisia, joissa asiat 'vain toimivat'), suosittelen asentamaan "vaihtoehtoisen konsolin", eli esimerkiksi Cygwin-ympäristön tai MSYS-työkalut.

Mahdollisia johtolankoja myös: UTF-8:n "Windows-merkistönimi" on 65001 ja komennolla "ccp" voi vaihtaa Windows-konsolin merkistöä.

jsbasic [22.02.2011 10:59:42]

#

eg: Niinhän se pitäisi loogisesti ajatellen olla. Unicode pitäisi säilöä C++:n merkkijonoissa (string ja char *) kahtena tavuna, eikä muuttaa yksitavuiseksi, jolloin tietoa katoaa.

Mutta miten saada windowsin kontrolli näyttämään koodipareja. Lähetän merkkijonon Windowsin richedit kontrollille näin:

SendMessage(hwnd, EM_REPLACESEL, (WPARAM)(BOOL)FALSE, (LPARAM)(LPCSTR)merkkijono);

Purkkaratkaisu tähän olisi kirjoittaa funktio, joka muuttaa yli 128 (tai alle 0) char-merkkiparit ääksi, ööksi, jne.

jalski [22.02.2011 14:13:07]

#

jsbasic kirjoitti:

eg: Niinhän se pitäisi loogisesti ajatellen olla. Unicode pitäisi säilöä C++:n merkkijonoissa (string ja char *) kahtena tavuna, eikä muuttaa yksitavuiseksi, jolloin tietoa katoaa.

UTF-8:n ollessa kyseessä menisi homma kyllä noin toimittaessa reisille, niin sanoakseni.

UTF-8 merkin pituushan on vaihtelevan mittainen, eikä suinkaan lukittu kahteen tavuun. Perustekstille tuo merkin pituus voi olla 1-3 tavua.

Tuon UTF-8 merkkijononhan voi yksinkertaisesti tallentaa peräkkäisinä tavuina ja parsia siitä UTF-8 merkit pois sopivan apufunktion ja silmukan avulla.

esim. Infernolle löytyy suoraan apufunktioksi kelpaava funktio byte2char(), mikä konvertoi sarjasta peräkkäisiä tavuja yhden UTF-8 merkin.

Grez [22.02.2011 14:32:24]

#

Niin tiestysti muistissa on järkevää käyttää 16-, tai jos haluaa koko Unicode merkistön käyttöön niin 32-bittisiä merkkimuuttuja ja merkkijonoja. Mutta UTF8:aa ei voi lukea vaan suoraan binäärinä muistipaikkaan, vaan se pitää käsitellä. En ole C++:aa pahemmin koodaillut, mutta luulisi sielläkin olevan kirjasto josta löytyy streamreaderi, joka osaa lukea UTF-8-virran vaikkapa 16-bittisillä merkeillä toimivaan merkkijonoon.

jsbasic [22.02.2011 18:21:48]

#

lainaus:

Tuon UTF-8 merkkijononhan voi yksinkertaisesti tallentaa peräkkäisinä tavuina ja parsia siitä UTF-8 merkit pois

Miten tuo "UTF-8 merkkijono" pitäisi ymmärtää?

lainaus:

Mutta UTF8:aa ei voi lukea vaan suoraan binäärinä muistipaikkaan, vaan se pitää käsitellä.

Mutta onhan C++:ssassa tuo wifstream, joka lukee wide char:eja. Se ei taida vielä toimia kunnolla ilman lisäkirjastoja. Mutta miksi ihmeessä pitäisi säilyttää tekstiä RAM-muistissa 32-bittisenä? Vai osaako jokin tietotyyppi säilöä 32-bittiseltä näyttävän luvun (mahdollisimman) 8-bittisenä?

eq [22.02.2011 19:30:37]

#

jsbasic kirjoitti:

lainaus:

Tuon UTF-8 merkkijononhan voi yksinkertaisesti tallentaa peräkkäisinä tavuina ja parsia siitä UTF-8 merkit pois

Miten tuo "UTF-8 merkkijono" pitäisi ymmärtää?

Merkkijono, joka koostuu UTF-8-merkeistä? UTF-8 on vain yksi tapa esittää Unicode-tekstiä; se on ASCII-yhteensopiva (ts. kaikki ASCII-teksti on myös UTF-8:aa; huomioithan, mitä ASCII on ja mitä se ei ole) ja siksi suosittu varsinkin Internet-käytössä.

UTF-8:ssa kaikki ASCIIn ulkopuolella olevat Unicode-merkit (eli Unicodemerkit 128:n jälkeen) esitetään useamman - kahden, kolmen tai neljän - tavun (tässä tapauksessa aina oktetin) yhdistelmänä, mihin nimen pääte '8' myös viittaa.

(Esimerkiksi UTF-16:ssa valtaosa yleisimmin käytetyistä merkeistä esitetään yhdellä 16-bittisellä arvolla - ja vain harvoin käytetään kahta 16-bittistä arvoa. UTF-32:ssa kaikki merkit esitetään yhden 32-bittisen arvon avulla)

jsbasic kirjoitti:

lainaus:

Mutta UTF8:aa ei voi lukea vaan suoraan binäärinä muistipaikkaan, vaan se pitää käsitellä.

Mutta onhan C++:ssassa tuo wifstream, joka lukee wide char:eja. Se ei taida vielä toimia kunnolla ilman lisäkirjastoja. Mutta miksi ihmeessä pitäisi säilyttää tekstiä RAM-muistissa 32-bittisenä? Vai osaako jokin tietotyyppi säilöä 32-bittiseltä näyttävän luvun (mahdollisimman) 8-bittisenä?

Mikä (ihme) on "mahdollisimman 8-bittinen"? Entä "32-bittiseltä näyttävä" luku?

Suosittelen opettelua ihan perusteista lähtien, arvailemalla voi päästä vain niin pitkälle. Lähteä voit vaikkapa siitä, mitä "8-bittinen" tai "32-bittinen" tarkoittaa.

(Sen jälkeen voisi olla hyödyllistä tutustua siihen, mitä Unicode on; ja selvittää sen jälkeen miten UTF-xx ja Unicode liittyvät toisiinsa, ja miten C:n (tai C++:n) "wide char" liittyy (ja ei liity!) koko touhuun).

jalski [22.02.2011 20:02:58]

#

jsbasic kirjoitti:

Miten tuo "UTF-8 merkkijono" pitäisi ymmärtää?

Ihan yksinkertaisesti siis, UTF-8 koodattu merkkijono on vain peräkkäisiä tavuja muistissa ja kyseessä on siis vaihtelevan mittainen koodaus, eli yksi perusmerkki voi koostua 1-3 tavusta.

lainaus:

Mutta UTF8:aa ei voi lukea vaan suoraan binäärinä muistipaikkaan, vaan se pitää käsitellä.

Tällä Grez siis tarkoitti, että jos tarkastellaan esimerkiksi serveriohjelmaa, mikä vastaanottaa asiakasohjelmalta vaihtelevan mittaisia merkkijonoja UTF-8 muodossa. Tuo tekstihän lähetetään ja vastaanotetaan kuitenkin oikeasti aina tavuina, eikä string muodossa. Nyt serveriohjelmalla on pieni ongelma: se vastaanottaa tavu kerrallaan, mutta UTF-8 perusmerkki voi kuitenkin siis koostua aina 1-3 tavusta ja serverin pitää pystyä näistä vastaanotetuista tavuista aina päättelemään milloin yksi kokonainen merkki on vastaanotettu.


Toteutin aikanani kiireessä tuosta toimivan, mutta ruman toteutuksen Infernon Limbolla koodivinkkeihin chat serveriä ja asiakasta varten. Sitä ei ikinä kuitenkaan varsinaisesti hyväksytty koodivinkkeihin, vaikka lisäsin tuohon jälkeenpäin kyllä kohtuullisen paljon kommenttejakin.

Luettavissa kuitenkin täällä

jsbasic [22.02.2011 20:35:29]

#

lainaus:

Mikä (ihme) on "mahdollisimman 8-bittinen"? Entä "32-bittiseltä näyttävä" luku?

Miten tuo pitäisi ilmaista? UTF-xx siis on (tai siihen sisältyy) eräänlainen tiivistysmenetelmä Unicodelle? Se vie muistia vähemmän kuin että jos jokainen symboli (kirjain tai väliviiva, lainausmerkki, asteriksi, obeliski, risuaita, jne) tallennettaisiin vaikka 32-bittisenä. Tämä perustuu siihen oletukseen/sopimukseen, että tiettyjä 128 symbolia käytetään useammin kuin toisia.

Mutta C/C++:n char on käsittääkseni kiinteäbittimääräinen tietotyyppi. Sen koko on aina 8 bittiä. Unicodea ei voi mitenkään esittää symboli per char, koska symboleita on enemmän kuin 256. Siksi on kai ok, että unicode-muotoinen teksti ladataan char* merkkijonoon niin, että 8 ensimmäistä bittiä laitetaan yhteen char-merkkiin, ja lisäbitit seuraaviin char:hin. Näin tapahtuu automaattisesti, kun UTF-tiedosto avataan ja luetaan ascii-muodossa:

ifstream file_stream;
file_stream.open("utf8-file.xml");

Vai onko homma mennyt jo tässä niille reisille?

Grez [22.02.2011 20:46:48]

#

jsbasic kirjoitti:

Mutta C/C++:n char on käsittääkseni kiinteäbittimääräinen tietotyyppi. Sen koko on aina 8 bittiä.

Mun käsittääkseni se on taattu olemaan vähintään 8 bittiä. Eli se vois olla jollain prosessoriarkkitehtuurilla vaikka 17 bittiä. PC-ohjelmoijalle taitaa kuitenkin olla lähinnä teoreettinen mahdollisuus. Sellaisia prosessoreita kuitenkin on, jossa CHAR_BITS on 9, 16 tai jopa 32.

jsbasic [22.02.2011 20:54:37]

#

lainaus:

Eli se vois olla jollain prosessoriarkkitehtuurilla vaikka 9 bittiä.

Eikös sen viime kädessä määrää kääntäjä eikä laitteisto? No väliäkö sillä kun haluat tahallaan viilata pilkkua. Minulla siis se on todennäköisesti 8. En ala testaamaan.

Grez [22.02.2011 21:00:58]

#

No, yleensä kääntäjä pyritään tekemään laitteiston ehdoilla, joten bittimäärän lähtökohta on laitteisto vaikka toki kääntäjä sen viimekädessä määrittää.

Enkä mä nyt halua viilata pilkkua, mutta oli pakko korjata kun laitoit virheellisen väitteen. Mun mielestä ei kannata esittää väitettä, jos ei oikeasti tiedä sen paikkaansapitävyydestä.

Jack Klein kirjoitti:

I used an Analog Devices 32-bit SHARC DSP a few years ago, I forget the exact model, where CHAR_BIT was 32 and all the integer types (this was before long long) were 32 bits.

I currently do a lot of work with a Texas Instruments DSP in the TMS32F28xx family where CHAR_BIT is 16 and the char, short, and int types all share the same representation and size.

eq [22.02.2011 21:08:04]

#

jsbasic kirjoitti:

Unicodea ei voi mitenkään esittää symboli per char, koska symboleita on enemmän kuin 256. Siksi on kai ok, että unicode-muotoinen teksti ladataan char* merkkijonoon niin, että 8 ensimmäistä bittiä laitetaan yhteen char-merkkiin, ja lisäbitit seuraaviin char:hin. Näin tapahtuu automaattisesti, kun UTF-tiedosto avataan ja luetaan ascii-muodossa:

Melkein. Ensinnäkään, mitään "ASCII-muodossa lukemista" ei ole olemassakaan; ns. tekstimuodossa luettaessa luku suoritetaan tavu kerrallaan, ja ajoympäristö saattaa korvata joitain merkkijonoja toisilla (ohjelmalle läpinäkyvästi). Toisekseen, UTF-8 ei ole aivan noin yksinkertainen, vaan Unicode-codepointit jaetaan useisiin tavuihin hieman eri logiikalla (josta hyvä dokumentaatio esimerkiksi internetissä..)

jsbasic [22.02.2011 21:27:14]

#

lainaus:

Enkä mä nyt halua viilata pilkkua, mutta oli pakko korjata kun laitoit virheellisen väitteen. Mun mielestä ei kannata esittää väitettä, jos ei oikeasti tiedä sen paikkaansapitävyydestä.

Olin tietoinen ongelmasta, mutta katsoin tässä asiayhteydessä tehokkaammaksi yleistää ja kertoa havainnollisen bittimäärän. Olisin voinut sanoa että "meillä kaikilla se on 8", joka olisi ollut hyvin todennäköistä.

lainaus:

Ensinnäkään, mitään "ASCII-muodossa lukemista" ei ole olemassakaan

Tämän mukaan on.
http://www.gamedev.net/page/resources/_/reference/programming/sweet-snippets/simple-file-io-using-c-r1127
Tässäkin kyse oli siitä etten pystynyt keksimään nopeasti parempaa ilmausta kuin tuon, jonka olin viimeksi kuullut. Olisiko ei-binäärinen ollut parempi? Sinulle se on "ns. tekstimuoto"?

Grez [22.02.2011 21:48:52]

#

jsbasic kirjoitti:

Olin tietoinen ongelmasta, mutta katsoin tässä asiayhteydessä tehokkaammaksi yleistää ja kertoa havainnollisen bittimäärän. Olisin voinut sanoa että "meillä kaikilla se on 8", joka olisi ollut hyvin todennäköistä.

Siis mistä ongelmasta? Olisit vaan voinut sanoa että "yleensä charissa on 8 bittiä". Se olisi ollut paljon lyhyempi ja selkeämpikin kuin "C/C++:n char on käsittääkseni kiinteäbittimääräinen tietotyyppi. Sen koko on aina 8 bittiä." En oikein pysty ymmärtämään miksi kirjoitit noin, jos kerran tiesit että C/C++:n char ei ole kiinteäbittimääräinen tietotyyppi ja sen koko ei ole aina 8 bittiä.

jsbasic [22.02.2011 22:12:24]

#

lainaus:

En oikein pysty ymmärtämään miksi kirjoitit noin, jos kerran tiesit että C/C++:n char ei ole kiinteäbittimääräinen tietotyyppi ja sen koko ei ole aina 8 bittiä.

"Kiinteäbittimääräinen" tietotyyppi tarkoittaa tässä tietysti sitä, että samassa ohjelmassa char:n kuluttama bittien määrä on vakio, eli siis X. Siten se ei koskaan sovellu UTF-tekstin varastointiin yhtä suoraviivaisesti kuin ascii-tekstin varastointiin.

Siis kysymys on tästä mitä eq kirjoitti:

lainaus:

Tiedoston lukemisessa ei kuitenkaan tapahdu mitään virheitä, sillä ainoa muunnos mitä (noin ymmärtääkseni) Windows-puolella tekstimuotoisille virroille tehdään, on rivinvaihtojen muunnokset; ja ne tapahtuvat turvallisesti ASCII-alueella eivätkä häiritse UTF-8-koodimerkkejä. Virheelliseltä näyttävä tulostus aiheutuukin täysin tulostusvaiheessa: ohjelma 'kirjoittaa' ulos-virtaan UTF-8:aa, mutta konsoli luulee saavansa joko latin1:ä (ISO-8859-1) tai Windows-1252:a (jälkimmäinen todennäköinen toki, Windowsista kun on kyse; tässä tapauksessa eroa ei kuitenkaan synny) - ja näyttää UTF-8-koodimerkit väärin.

Eli voiko, ja kannattaako, lukea UTF-8 tiedosto char* tai string-merkkijonoon, ja alkaa hakea ongelmaan ratkaisua tulostuksesta, kuten eq:n kirjoituksesta voi päätellä. Vai meneekö homma tässä tapauksessa niille reisille, kuten Jalski sanoi?

Ilmeisesti tähän ei ole valmista ratkaisua. Pitää käyttää random kirjastoja ja yrittää sovittaa UTF-8:n eri toteutustapoja yhteen...

Käsittääkseni UTF ei itsessään määrittele mitä tietotyyppiä sen varastoimiseen C/C++ -kielen tietorakenteisiin tulee käyttää.

Metabolix [22.02.2011 22:37:53]

#

Jos tiedostolle ei tarvitse tehdä mitään ihmeitä, tavallinen string on käytännöllisin vaihtoehto. Linuxissahan ohjelma toimii silloin todennäköisesti suoraan. Windowsiin joudut sitten kikkailemaan jonkin vaihtoehtoisen ratkaisun tai muunnoksen tulostamiseen.

Onko yleensäkään tarpeen tehdä ohjelmasta interaktiivista komentoriviohjelmaa tai tukea koko Unicode-merkistöä?

jsbasic [22.02.2011 22:51:49]

#

lainaus:

Onko yleensäkään tarpeen tehdä ohjelmasta interaktiivista komentoriviohjelmaa

Eihän tässä komentorivistä ole kysymys, vaan teksti pitäisi saada ennen kaikkea windowsin-ikkunaan, tarkalleen ottaen richedit-kontrolliin. Mutta kyllä mielestäni komentorivi on tarpeen, ainakin testattaessa GUI-pohjaista ohjelmaa. Valmisohjelmista ainakin Blenderissä on mukana tekstikonsoli.

lainaus:

...tai tukea koko Unicode-merkistöä?

No en tiedä. Käytän nyt aluksi itse koodaamani muunnosta åäö -kirjaimille. Mutta on paljon erikoismerkkejä jotka tulostuvat väärin.

Grez [22.02.2011 22:55:29]

#

No eikös ne Windowsin GUI-kontrollit ole nykyisissä versioissa Unicode-tukisia, eli sellaiseen ei IMO pitäisi olla yhtään mitään ongemlaa saada kaikki perustason 60000+ merkkiä näkymään kivasti.

Eli wchar* vaan laulamaan. Tietty se UTF8 tavara pitää lukea tuollaiseen, mutta jos nyt tosiaan ei C++:sta löydy valmista kirjastoa niin sen implementoi itse 5 minuutissa.

jsbasic [23.02.2011 13:07:20]

#

lainaus:

Eli wchar* vaan laulamaan.

Niin ja miksi? Tässä sanotaan näin:

http://en.wikipedia.org/wiki/Wide_character

lainaus:

programs that need to be portable across any C or C++ compiler should not use wchar_t for storing Unicode text.

Artikkelissa kuitenkin myös:

lainaus:

The Microsoft Windows application programming interfaces Win32 and Win64, as well as the Java and .Net Framework platforms, require that wide character variables be defined as 16-bit values, and that characters be encoded using UTF-16 (due to former use of UCS-2)

Eli nykyään käytetään laajasti UTF-16 -koodausta ja se toteutetaan kiinteillä 16-bitin arvoilla. (Siitä huolimatta että se vie enemmän tilaa.) Tiedostoon teksti kuitenkin ilmeisesti tallennetaan vaihtelevan pituisina arvoina, eli a-kirjain vie 8 bittiä, ja ä-kirjain vie 16 bittiä. Jos tiedoston lukee char *-merkkijonoon, se on muunnettava 16-bittiseksi ennen kuin windows sen ymmärtää.

Windows käyttää mutten seuraavia merkkijonoja:
http://www.experts-exchange.com/Programming/System/Windows__Programming/MFC/Q_22103802.html

lainaus:

LPCSTR : Constant string of char i.e. 'const char*'
LPCWSTR : Constant string of WCHAR i.e. 'const WCHAR*' , ( WCHAR : Unicode character )
LPTSTR : String of TCHAR i.e. 'TCHAR*' , ( TCHAR : MBCS or Unicode character depending on preprocessor settings )

eq [23.02.2011 17:51:18]

#

Jos ohjelma käyttää Windows-GUI-komponentteja, se ei joka tapauksessa ole alustariippumaton, ja voit hyvin käyttää wchar_t:tä - Windowsissa se on aina 16-bittinen ja siihen on tarkoitus tallettaa UTF-16-arvoja (käytännössä funktiot olettavat UCS-2). Myös tiedosto kannattaa ehkäpä tässä muodossa tallettaa, ihan helppouden nimissä - vaikka se hieman enemmän tilaa veisikin (tosin standardi-C++-funktiot *eivät* lisää BOM-merkkejä yms., tarvittaessa voit käyttää alustan tarjoamia IO-funktioita, olethan siihen muutenkin sidoksissa.)

Maksimaalisen Windows-yhteensopivuuden nimissä Windows-ohjelmoinnissa olisi kai tarkoitus käyttää TCHAR-tyyppiä ja -funktioita; ja käännöksen yhteydessä valita käännetäänkö ohjelma locale- vai Unicode-muodossa.

Alustariippumattomiin (huono termi) GUI-ohjelmiin käyttäisin itse lähtökohtaisesti Qt:ta. Qt-maailmassa tekstiä käsitellään lähinnä QString-olioissa, mutta se tukee mukavasti muunnoksia molempiin suuntiin UTF-8/16/32/ASCII/latin1/(miljoona muuta localea...) jne., käyttäen itse UTF-16:a sisäisesti (toki Qt tarjoaa myös muitakin ei-GUI-apuja, esim. IO:hon liittyen).


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta