Pobieranie polskich znaków z pliku

0
#ifndef UNICODE
#define UNICODE
#endif


#include <iostream>
#include <Windows.h>
#include <string>
#include <fstream>


using namespace std;


int main(void)
{
	wstring myString;
	wifstream iFile;
	
	iFile.open(L"file1.txt");

	getline(iFile , myString);

	wcout<<myString<<endl;

	MessageBoxW(0,myString.c_str() , L"komunikat",0);

	system("PAUSE");
}

W file1.txt mamy napis: "ęóąłźćń Witaj świecie!" . Dlaczego , mimo użycia podwójnego kodowania zamiast polskich znaków wyskakują krzaczki, i to zarówno w konsoli jak i w okienku wiadomości?

0

co to jest podwójne kodowanie? w jakiej stronie kodowej masz zapisane te polskie literki? 852? w1250? utf-8? utf-16?
dlaczego MessageBoxW, a nie MessageBoxA (czyli MessageBox)? rozumiesz różnicę pomiędzy funkcjami winapi *W i *A?

0
ŁF napisał(a)

co to jest podwójne kodowanie? w jakiej stronie kodowej masz zapisane te polskie literki? 852? w1250? utf-8? utf-16?
dlaczego MessageBoxW, a nie MessageBoxA (czyli MessageBox)? rozumiesz różnicę pomiędzy funkcjami winapi *W i *A?

Jak bym się gdzieś pomylił to proszę mnie poprawić .

W "podwójnym kodowaniu" każdy znak jest zapisany na dwóch bajtach( dzięki temu mamy tyle kombinacji, że spokojnie można zmieścić wszystkie znaki ze wszystkich języków nie korzystając ze stron kodowych, czyli np. w jednym pliku mogą współistnieć ogonki, cyrylica i chińskie znaki).

Plik file1.txt był zapisany w zwykłym notepadzie, gdzie są cztery kodowania do wyboru - ANSI, UTF-8, UNICODE ,UNICODE BIG ENDIAN . ( próbowałem zapisać na 4 sposoby i za każdym razem wyskakiwały inne znaki, ale nigdy te o które mi chodziło).

MessageBoxW korzysta z UNICODE, a MessageBoxA z ANSI .

Funkcje z A wewnętrznie dokonują konwersji do wide charów i wywołują funkcję z W. Funkcje W są więc szybsze, lepsze i w ogóle zalecane.

Źródło: "Windows via C++" Richter Nasarre.

Osobiście nie wiem dlaczego program nie koduje poprawnie polskich znaków, nie mam pojęcia co może być źle. Byłbym wdzięczny gdyby ktoś to wytłumaczył :)

0

w pliku zapisujesz w utf-16 (to jest to Twoje "podwójne kodowanie"). wczytujesz do wstring i wyświetlasz używając *W - i tak powinno być dobrze.
skoro jest źle, to albo w pliku nie masz utf-16 i powinieneś użyć MultiByteToWideChar(), albo zapisałeś plik w notatniku i przestraszyłeś się trzybajtowego nagłówka BOM, albo ja się nie znam.

1

dlaczego MessageBoxW, a nie MessageBoxA (czyli MessageBox)? rozumiesz różnicę pomiędzy funkcjami winapi *W i *A?

A ty rozumiesz? MessageBox oznacza MessageBoxA jeśli nie zdefiniowano #define UNICODE, ale MessageBoxW jeśli zdefiniowano.

A co do tematu: to nie poleci. Nie bez dużego kombinowania.
Ale możesz zamiast wifstream użyć starego dobrego FILE*, z rozszerzeniem Microsoftu "ccs=UNICODE":

#ifndef UNICODE
#define UNICODE
#endif
 
#include <iostream>
#include <Windows.h>
#include <string>
#include <fstream>
#include <clocale> 
#include <cstdio>
 
using namespace std;
 
int main(void)
{
    setlocale(LC_CTYPE,".1250");
    wchar_t myString[256];
    FILE *iFile = _wfopen(L"file1.txt", L"r, ccs=UNICODE");

    fgetws(myString, 256, iFile); 
 
    wcout<<myString<<endl;
 
    MessageBoxW(0, myString, L"komunikat", 0);

    fclose(iFile);
 
    system("PAUSE");
}

w ten sposób działa w konsoli i w okienku, i to niezależnie czy plik jest zakodowany w UTF-8, UTF-16 czy ANSI.

PS. _wfopen() różni się od fopen() tylko tym, że przyjmuje parametry jako widestringi. nie ma to wpływu na kodowanie samego pliku.

1 użytkowników online, w tym zalogowanych: 0, gości: 1