[C++] Polskie znaki

0

Czy zna ktoś łatwiejszy sposób, by konsola wyświetlała polskie znaki, niż ten?

     char pz1, pz2;
     pz1 = 152;  //ś
     pz2 = 134;  //ć 
     
     cout << "Cze" << pz1 << pz2;

Rezultat:
Cześć

Robię program, który wymaga polskich znaków, ale przypisywanie nowych wartości zmiennym trochę przedłuża mi pracę...

0

Może stworzenie odpowiedniego makra rozwiązało by problem, mianowicie makro to miało by analizować kod programu, wyszukiwać polskie znaki i podmieniać je na odpowiednie stałe. Nie wiem jak coś takiego napisać ale może komuś sie uda...

PS. z tego co wiem to cierpliwość w programowaniu jest jedną z podstaw ;-)

0

mozesz pisac normalnie, np. "żółty" i wyswietlac to cout'em. jesli po czyms takim w konsoli zamiast znakow narodowych wyswietlaja sie krzaki, to znaczy ze masz nieprawidlowo ustawione locale -- w standardowej bibliotece C++ jest zestaw funkcji ktore pozwalaja ustawic strumien aby korzystal z danego kodowania, o ile pamietam jest to metoda imbue, np. cout.imbue(..cos..) i juz masz ustawione PL-pl.. poza tym, chyba najbezpieczniej jest po prostu korzystac z unicode, czyli widestringow:

#define UNICODE
#include <iostream>
#include <wstring>

std::wstring uni_napis = L"zażółć gęślą jaźń";
std::wcout << uni_napis << endl;

@Kod - cos w tym stylu. string!=wstring. string bazuje na char, wstring na wchar_t. L"napis" to nie blad - w ten sposob oznacza sie cstringi const wchar_t* zamiast const char*

0

Hmm.. Jesteś pewien, czy ten kod jest właściwy? Bo mój kompilator ma zastrzeżenia do wcout (używam Dev-C++)

Najpierw mi pisze, że wcout nie należy do std, a po usunięciu std że jest nie zadeklarowany...

0

tak jak mowilem kod jest mniej-wiecej.. aktualnie probuje przygotowac poprawny przyklad..

przykaldowo:

#include <iostream>
#include <locale>
#include <string>

int main()
{   using namespace std;
    cout.imbue(locale("pl_PL"));
    string name = cout.getloc().name();
    cout << "locale=" << name << endl;

    string napis = "zażółć gęślą jaźń";
    cout << napis.size() << endl;
    cout << napis << endl;
    return 0;
}

na gcc/G++: gcc version 3.3.6 (PLD Linux) tworzy wyjscie:

locale=pl_PL
17
zażółć gęślą jaźń

a wiec idealnie: 17 znakow w stringu, napis wypisany.. jesli wypisze krzaki - to znaczy ze system nieprawilowo obsluguje pl_PL ---- acz wtedy powinien rzucic wyjatkiem podczas imbue(locale("pl_PL

natomiast uparlem sie z widestringami..:

#include <iostream>
#include <locale>
#include <string>

int main()
{   using namespace std;
    wcout.imbue(locale("pl_PL"));
    string name = wcout.getloc().name();
    cout << "locale=" << name << endl;

    wstring napis = L"zażółć gęślą jaźń";
    wcout << napis.size() << endl;
    wcout << napis << endl;
    if(!wcout){wcout.clear();wcout << "streamput failed" <<endl;}
    return 0;
}

wyrzuca:

locale=pl_PL
17
zastreamput failed

i do prawdy nie wiem czemu.. widestring ma tez 17 znakow, czyli nic nie zostalo uciele. natomiast proba wrzucenia znaku L'ż' na wcout, powoduje wejscie w stan FAIL.. no i na razie na tym fakcie utknalem. w kazdym badz razie jak widac sam wstring dziala - problem za pewne lezy w ustawieniu locale i charsetu

0

Problem tkwi jedynie w edytorze i zastosowaniu odpowiedniego kodowania znaków. Na razie pisz sobie w dev'ie normalnie i nie przejmuj się, że w konsoli wyskakują krzaczki. Jak skończysz pisać program to otwórz go w jakimś edytorze tekstowym pozwalającym na zmianę kodowania (np. PSPAd jest fajny). Zmień kodowanie znaków na OEM i zapisz. Ponownie otwórz w dev'ie, tym razem tu zobaczysz krzaczki, ale po kompilacji w konsoli ujrzysz polskie ogonki.

0

ś jest tak

char a='\230'

ściana tak

cout<<"\230ciana";

i tak dalej

0

Można skorzystać z funkcji, która zmienia kod podanych polskich znaków na odpowiednie znaki z tablicy ACII. Działa równie dobrze.

std::string PL(std::string Znak)
{
       for (int i = 0; i < Znak.length(); i ++)
       {
               switch(Znak[i])
               {
                       case 'ą':
                               Znak[i] = static_cast<char>(165);
                       break;

                       case 'ć':
                               Znak[i] = static_cast<char>(134);
                       break;

                       case 'ę':
                               Znak[i] = static_cast<char>(169);
                       break;

                       case 'ł':
                               Znak[i] = static_cast<char>(136);
                       break;

                       case 'ń':
                               Znak[i] = static_cast<char>(228);
                       break;

                       case 'ó':
                               Znak[i] = static_cast<char>(162);
                       break;

                       case 'ś':
                               Znak[i] = static_cast<char>(152);
                       break;

                       case 'ź':
                               Znak[i] = static_cast<char>(171);
                       break;

                       case 'ż':
                               Znak[i] = static_cast<char>(190);
                       break;

                       case 'Ą':
                               Znak[i] = static_cast<char>(164);
                       break;

                       case 'Ć':
                               Znak[i] = static_cast<char>(143);
                       break;

                       case 'Ę':
                               Znak[i] = static_cast<char>(168);
                       break;

                       case 'Ł':
                               Znak[i] = static_cast<char>(157);
                       break;

                       case 'Ń':
                               Znak[i] = static_cast<char>(227);
                       break;

                       case 'Ó':
                               Znak[i] = static_cast<char>(224);
                       break;

                       case 'Ś':
                               Znak[i] = static_cast<char>(151);
                       break;

                       case 'Ź':
                               Znak[i] = static_cast<char>(141);
                       break;

                       case 'Ż':
                               Znak[i] = static_cast<char>(189);
                       break;
               }
       }
       return Znak;
}

W wywołaniu funkcji pomiędzy "" wpisujemy napis, w którym występują polskie znaki.
Przykład zastosowania:

std::cout << PL("Kółko i krzyżyk");
0

Oj oj oj , po co takie komplikacje. Problem jest banalny. po prostu dla dev'a literka ś ma kod 156, a w konsoli ś to 152. Po co sie męczyć z jakimiś nic nie mówiącymi liczbami itp. Pisz w devie sobie normalnie śćź, po skończeniu konwersja na właściwe kodowanie i tyle. zero problemów.

0
quetzalcoatl napisał(a)

natomiast uparlem sie z widestringami..:
[...]
i do prawdy nie wiem czemu.. widestring ma tez 17 znakow, czyli nic nie zostalo uciele. natomiast proba wrzucenia znaku L'ż' na wcout, powoduje wejscie w stan FAIL.. no i na razie na tym fakcie utknalem. w kazdym badz razie jak widac sam wstring dziala - problem za pewne lezy w ustawieniu locale i charsetu

wcout.imbue(locale(".OCP"));
0

Problem jest taki, że cmd.exe ma kodowanie dosowe 852 a system windows-1250 albo unicode. I jest to problem cmd a nie programu.

W ustawieniach cmd.exe (prawym myszy pasek tytułu -> properties -> zakładka Font) mam do wyboru Lucida Console i Raster Fonts, które było ustawione i z tym mi nie działało ale z Lucidą poszło ładnie. Może dlatego, że to true type? Nie wiem.

No dobra a o co chodzi.
jest takie ładne polecenie:
mode con cp select=1250
no może nie tak ładne jak
chcp 1250
Jedno i drugie ustawi kodowanie cp-1250 jakiego zapewne używa program :) Samo chcp pokaże jakie jest ustawione.

odpowiednie numerki to
852 DOS
1250 cp-1250
28592 iso-8859-2
65001 utf-8

Zapisałem w tych kodowaniach testowy tekst i poleceniem type wyświetlałem go. Działo :) A z jakimś przykładowym programem nie sprawdzę, bo popsuli instalację deva na zdalnej, uczelnianej maszynie a nie chce mi się restartować do Windowsa.

0

a wiec idealnie: 17 znakow w stringu, napis wypisany.. jesli wypisze krzaki - to znaczy ze system nieprawilowo obsluguje pl_PL ---- acz wtedy powinien rzucic wyjatkiem podczas imbue(locale("pl_PL

Dla wyczerpania tematu: Vista takowy wyjątek powoduje.

0

Win XP też...

0

Linuks z dobrym locale wyświetla dobrze.

0

Na XP z tym co podałem wcześniej też ;)

0

Zmodyfikowałem i połączyłem dwa inne kody, przez co powstał jeden. Aplikacja czyta tekst z pliku tekst.txt, zapobiega robieniu się "krzaczków" z polskich znaków. znak _ jest znakiem spacji a znak | znakiem kolejnego wiersza (ENTER). Te znaki muszą tam być, bo gdyby nie one, aplikacja czytałaby tylko ostatni wyraz... Moze wie ktoś jak to poprawic? :-|

kod:

#include <iostream> 
#include <string> 
#include <fstream>

using namespace std ; 

void Popraw(string napis) 
{ 
   char znak;
   int dlugosc = napis.length(); 
   for(int i = 0; i < dlugosc; i++) //Dzieli tekst na litery
   
   {
           switch(napis[i])
           {
                           case 'ą':
                                znak = 165;
                                cout << znak;
                                break;
                           case 'Ą':
                                znak = 164;
                                cout << znak;
                                break;
                           case 'ć':
                                znak = 134;
                                cout << znak;
                                break;
                           case 'Ć':
                                znak = 143;
                                cout << znak;
                                break;
                           case 'ę':
                                znak = 169;
                                cout << znak;
                                break;
                           case 'Ę':
                                znak = 168;
                                cout << znak;
                                break;
                           case 'ł':
                                znak = 136;
                                cout << znak;
                                break;
                           case 'Ł':
                                znak = 157;
                                cout << znak;
                                break;
                           case 'ń':
                                znak = 228;
                                cout << znak;
                                break;
                           case 'Ń':
                                znak = 227;
                                cout << znak;
                                break;
                           case 'ó':
                                znak = 162;
                                cout << znak;
                                break;
                           case 'Ó':
                                znak = 224;
                                cout << znak;
                                break;
                           case 'ś':
                                znak = 152;
                                cout << znak;
                                break;
                           case 'Ś':
                                znak = 151;
                                cout << znak;
                                break;
                           case 'ż':
                                znak = 190;
                                cout << znak;
                                break;
                           case 'Ż':
                                znak = 189;
                                cout << znak;
                                break;
                           case 'ź':
                                znak = 171;
                                cout << znak;
                                break;
                           case 'Ź':
                                znak = 141;
                                cout << znak;
                                break;
                           case '_':
                                cout << " ";
                                break;
                           case '|':
                                cout << endl;
                                break;
                           default:
                                   cout << napis[i];
           }
   } 
} 

//-------------------------------------------------------

int main() 
{ 
  string tekst;
  int i;
  
  ifstream f("tekst.txt");
  while(f >> tekst) i++;
  f.close();
  
  Popraw(tekst) ; 
  system("pause") ; 
  return 0 ; 
}

tekst.txt
Zażółć_gęślą_jaźń|Zażółć_gęślą_jaźń

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

0

Użyj getline zamiast operator>>.

0

Zamiast

while(f >> tekst) i++;

użyjgetline(f, tekst);

Ten kod wczyta wszystkie wyrazy do znaku nowej linii - 'n'. Jeżeli chcesz zmienić ograniczenie np. do # to kod będzie wyglądać tak:
```cpp
getline(f, tekst, '#');
0

OMG. Nie tędy droga. Albo unicode, albo tak jak pisałem - zmiana kodowania znaków przy pomocy innego edytora tekstu.

0

Jeśli dobrze myśle, na początku kodu miałem umieścić

#define UNICODE

i dalej pisać normalnie... tylko co dziwne... To nie działa :-/

0

UNICODE ma się nijak do standardowej biblioteki C++ - to nie WinAPI ;).

0

Macro UNICODE na nic ci nie potrzebne. Pamiętaj tylko, że każdy łańcuch piszesz z literką L na końcu jak np "ala ma kota"L . No i nie 'cout' tylko 'wcout', nie 'strlen' tylko 'wcslen', nie 'string' tylko 'basic_string<wchar_t>' itp.

0

nie 'string' tylko 'basic_string<wchar_t>' itp.

nie string tylko wstring itp. :>

0

0x666, Dziex, majorek:
Rzeczywiscie, ten fragment kodu ktory wkleilem jest "na linuksa", tam sie kodowanie oznacza jako pl_pl.
Na windowsie - pojecia nie mam :) jesli .OCP proponowane przez 0x666 dziala, to fajnie wiedziec

BAT:
moze przeczytaj i sprobuj zrozumiec to co mowia Ci, ktorzy nie podrzucaja Tobie watpliwych kopiuj-wklejek

adf89 napisał(a)

Pamiętaj tylko, że każdy łańcuch piszesz z literką L na końcu jak np "ala ma kota"L

nie "ala ma kota"L, tylko L"ala ma kota". przy cstringach jest prefix, sufix - przy liczbach

0
quetzalcoatl_ napisał(a)

Rzeczywiscie, ten fragment kodu ktory wkleilem jest "na linuksa", tam sie kodowanie oznacza jako pl_pl. Na windowsie - pojecia nie mam :)

Polish_Poland

Dodam jeszcze, że zamiast samego ".OCP" lepiej określić w całości ustawienia lokalne np:

wcout.imbue(locale("Polish_Poland.852"));
wcin.imbue(locale("Polish_Poland.852"));

wtedy będzie pewność, że program będzie wyświetlał ogonki na systemie z inną domyślną stroną kodową.

<font size="1">PS. oczywiście mogę się mylić</span> ;-P

0
quetzalcoatl_ napisał(a)

BAT:
moze przeczytaj i sprobuj zrozumiec to co mowia Ci, ktorzy nie podrzucaja Tobie watpliwych kopiuj-wklejek

Czytam i staram się zrozumieć :-)

0

ok.. jesli bedziesz mial z tym problemy, obiecuje napisac o tym 'bloga'.. ale to tak w ciagu 3-4 dni, cienko mi z czasem ostatnio..

0

locale locpol("Polish_Poland");
locale::global(locpol);
cout.imbue(locpol);
cin.imbue(locpol);

ten kod załatwia sprawę (na pewno w MS VC++ 2008)

0

tak.. i IIR, abstrahujac od Polish_Poland vel pl_PL vel .ocp itede, powinno rozwiazywac wszedzie

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