Polskie znaki w konsoli

Stronę tą wyświetlono już: 305 razy

W systemach Windows w konsoli stosowane jest inne kodowanie znaków niż domyślne kodowanie znaków w plikach kodów źródłowych .cpp, .h i .c. Informacje o stronie kodowej używanej w konsoli Windowsa można wyświetlić uruchamiając konsolę (wind+r i okienku, które się pojawi wpisać cmd) i wpisując polecenie chcp.

C:\Users\User_name>chcp
Aktywna strona kodowa: 852

C:\Users\User_name>

Niestety Dev-C++ nie obsługuje tej strony kodowej, co ułatwiłoby zadanie, bo wystarczyłoby zapisać pliki z kodem źródłowym z kodowaniem 852 i wszystko by działało cacy. Istnieje pewne częściowe rozwiązanie tego problemu, wiążące się z wykorzystaniem funkcji setlocale w sposób następujący:

Listing 1
  1. #include <iostream>
  2. #include <locale.h>
  3. using namespace std;
  4. int main(){
  5. setlocale(LC_CTYPE, "Polish");
  6. cout<<"Zażółć gęślą jaźń"<<endl<<endl;
  7. cout<<"Wciśnij enter, aby zamknąć program...";
  8. cin.get();
  9. return 0;
  10. }

Wynik działania programu:

Zażółć gęślą jaźń

Wciśnij enter, aby zamknąć program...

No i ktoś mógłby teraz powiedzieć: no i gra i buczy, wszystko działa, więc w czym problem? Problem pojawia się, gdy chcesz wprowadzić dane tekstowe z klawiatury i te dane zawierają polskie znaki diakrytyczne, oto przykład:

Listing 2
  1. #include <iostream>
  2. #include <locale.h>
  3. using namespace std;
  4. int main(){
  5. setlocale(LC_CTYPE, "Polish");
  6. cout<<"Zażółć gęślą jaźń"<<endl<<endl;
  7. char str[50] = {0,};
  8. cout<<"Podaj jakiś tekst zwierający polskie znaki diakrytyczne: ";
  9. cin>>str;
  10. cout<<endl<<endl<<"Testowy tekst: "<<str<<endl<<endl;
  11. cout<<"Wciśnij enter, aby zamknąć program...";
  12. cin.get();
  13. return 0;
  14. }

Przykładowy rezultat działania programu:

Zażółć gęślą jaźń

Podaj jakiś tekst zwierający polskie znaki diakrytyczne: Zażółć gęślą jaźń


Testowy tekst: Zaľ˘?┼ gc?lĄ ja«ä

Wciśnij enter, aby zamknąć program...

Jak widzicie, to rozwiązanie z setlocale nie zawsze się sprawdza i ma jeszcze jedną wadę: załączając locale.h zwiększa się objętość programu i to tylko dlatego, że strona kodowa plików z kodem źródłowym nie pasuje do strony kodowej konsoli. Aby rozwiązać ten problem, wystarczyłoby tuż przed ostateczną kompilacją programu zmienić stronę kodową plików źródłowych. Do tego celu można by się posłużyć jakimś programem umożliwiającym zmianę kodowania danych, ja jednak mam nieco inne rozwiązanie. Otóż tak się składa, że napisałem sobie mały programik, który po przeciągnięciu i upuszczeniu na jego ikonę plików .cpp, .h i .c automatycznie zamienia kodowanie znaków i to (uwaga, uwaga) tylko tekstu zawartego pomiędzy cudzysłowami "" (a więc nie rusza komentarzy pod warunkiem, że w nich nie ma cudzysłowu (to jedyny mankament tego rozwiązania). Żeby program jednak zadziałał poprawnie w każdym z zmienianych plików na samym początku należy wstawić taką oto linijkę komentarza:

Listing 3
  1. // codepage:ąćęłńóśżźĄĆĘŁŃÓŚŻŹ

Ta linijka zawiera istotne informacje, jakie znaki mają zostać podmienione. Teraz kod programu do skompilowania będzie następujący:

Listing 4
  1. // codepage:ąćęłńóśżźĄĆĘŁŃÓŚŻŹ
  2. #include <iostream>
  3. using namespace std;
  4. int main(){
  5. cout<<"Zażółć gęślą jaźń"<<endl<<endl; // ąćęłńóśżźĄĆĘŁŃÓŚŻŹ
  6. char str[50] = {0,};
  7. cout<<"Podaj jakiś tekst zwierający polskie znaki diakrytyczne: ";
  8. cin.getline(str, sizeof(str)/ sizeof(char));
  9. cout<<endl<<endl<<"Testowy tekst: "<<str<<endl<<endl;
  10. cout<<"Wciśnij enter, aby zamknąć program...";
  11. cin.get();
  12. return 0;
  13. }

Przykładowy efekt działania programu:

Za┐ˇ│Š gŕťl╣ jač˝

Podaj jakiť tekst zwieraj╣cy polskie znaki diakrytyczne: Zażółć gęślą jaźń


Testowy tekst: Zażółć gęślą jaźń

Wciťnij enter, aby zamkn╣Š program...

Hej - zaraz ktoś powie, miały być polskie znaki? Będą, będą, tylko najpierw przekodować trzeba plik z kodem na zapis zgodny z kodowaniem 852, po zrobieniu tego kod programu w Dev-C++ będzie wyglądał następująco:

Listing 5
  1. // codepage:Ą†©ˆä˘˜ľ«¤Ź¨ťăŕ—˝Ť
  2. #include <iostream>
  3. using namespace std;
  4. int main(){
  5. cout<<"Zaľ˘ˆ† g©˜lĄ ja«ä"<<endl<<endl; // ąćęłńóśżźĄĆĘŁŃÓŚŻŹ
  6. char str[50] = {0,};
  7. cout<<"Podaj jaki˜ tekst zwierajĄcy polskie znaki diakrytyczne: ";
  8. cin.getline(str, sizeof(str)/ sizeof(char));
  9. cout<<endl<<endl<<"Testowy tekst: "<<str<<endl<<endl;
  10. cout<<"Wci˜nij enter, aby zamknĄ† program...";
  11. cin.get();
  12. return 0;
  13. }

Przykład działania programu:

Zażółć gęślą jaźń

Podaj jakiś tekst zwierający polskie znaki diakrytyczne: Zażółć gęślą jaźń


Testowy tekst: Zażółć gęślą jaźń

Wciśnij enter, aby zamknąć program...

Nie trudno zauważyć, że w kodzie programu zamienione zostały znaki strony kodowej:

Listing 6
  1. // codepage:Ą†©ˆä˘˜ľ«¤Ź¨ťăŕ—˝Ť

Dzięki takiemu zabiegowi, po ponownym upuszczeniu pliku na ikonę programu zamieniającego kodowanie otrzyma się standardowo zakodowany plik z kodowaniem Windows 1250, które to kodowanie obsługuje już poprawnie Dev-C++.

Pod Linuksem stosowane jest kodowanie UTF-8, a więc aby na tym systemie poprawnie obsługiwać polskie znaki, plik musi być zakodowany w UTF-8.

Nie daję żadnej gwarancji, że program PolskieZnaki.exe jest pozbawiony wad, w związku z czym używasz go na własną odpowiedzialność.

Załączniki:

Program do zmiany znaków z Windows-1250 na 852 i na odwrót

Komentarze