cout, konsola Windows i polskie znaki

0

Witam! Tak, wiem, że temat wałkowany był już nieraz, ale nigdzie nie znalazłem satysfakcjonującej mnie odpowiedzi.

Otóż potrzebuję, aby działały polskie znaki w konsoli systemu Windows drukowane cout'em. Sęk w tym, że z powodu budowania programu pod 2 platformy nie bardzo odpowiadają mi żadne rozwiązania, w tym cout << PL("Zażółć gęślą jaźń") << endl;

Miałem kiedyś plik nagłówkowy podobny do tego:

#include <iostream>

using namespace std;

string PL(string znak)
{
for (unsigned 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;
}

Ale działał on tak, że właśnie nie potrzeba było specjalnej składni cout'a, tylko normalnie można było napisać `cout << "Zażółć gęślą jaźń" << endl;' i działało, nie potrzeba było nic więcej, ale niestety nie potrafię przerobić tego pliku nagłówkowego w ten sposób. Czy znajdzie się jakieś rozwiązanie?

0

poczytaj o "wcout".

0
#include <iostream>
#include <clocale>
 
using namespace std;

int main()
{
	setlocale(LC_CTYPE,".1250");
	cout << "zażółć gęślą jaźń" << endl;
}

metoda działa pod Vistą i Win7.
pod XP działa ale niestety nie na wszystkich kompach — nie doszedłem od czego to zależy.

rozwiązaniem bez żadnego kombinowania w kodzie jest też zapisanie pliku źródłowego w stronie kodowej CP852.

0
Azarien napisał(a)
#include <iostream>
#include <clocale>
 
using namespace std;

int main()
{
	setlocale(LC_CTYPE,".1250");
	cout << "zażółć gęślą jaźń" << endl;
}

metoda działa pod Vistą i Win7.
pod XP działa ale niestety nie na wszystkich kompach — nie doszedłem od czego to zależy.

rozwiązaniem bez żadnego kombinowania w kodzie jest też zapisanie pliku źródłowego w stronie kodowej CP852.

Niestety, nie pomogło, jedynie są trochę inne krzaczki :D

0

a w jakim kodowaniu zapisujesz w ogóle ten plik?

0

Zapewne w domyślnym C::B -> UTF-8 ;).

0

Tak, w UTF-8

0

Ja zawsze używałem:
setlocale(LC_ALL,"");

0

Jedyne co udaje się uzyskać to inne krzaczki, polskich znaków niet.

0

Tyle razy na forum temat poruszaliśmy, tyle rozwiązań podaliśmy, testowaliśmy rozwiązania pod różne systemy, że powinieneś się wstydzić, że nie użyłeś wyszukiwarki. No, ale niech mój avatar cię nie onieśmiela.

0
Rev napisał(a)

Tyle razy na forum temat poruszaliśmy, tyle rozwiązań podaliśmy, testowaliśmy rozwiązania pod różne systemy, że powinieneś się wstydzić, że nie użyłeś wyszukiwarki. No, ale niech mój avatar cię nie onieśmiela.

Heh, mówię, że szukałem, ale co z tego, skoro jedyne rozwiązanie, które działa to plik nagłówkowy z pierwszego postu i używanie cout << PL("Zażółć gęślą jaźń") << endl; co mi się nie uśmiecha

0

Kłamiesz.

0
Rev napisał(a)

Kłamiesz.

Nie, nie kłamię. Próbowałem różnych rozwiązań z różnymi czcionkami.

0

Jakie czcionki? Co mają do tego czcionki?

Zacznijmy od tego, że chcesz niemożliwego - nie da się osiągnąć tego, czego dokładnie chcesz, tj. mieć plik (i literały) zapisane w UTF-8 i wypisywać Unicode bez zmiany kodowania literałów w runtime. Konsola Windows wypisuje znaki zgodnie z kodowaniem, które ma ustawione (i też nie jest przystosowana do Unicode) i jest to najczęściej dosowy codepage 852. I w tym kodowaniu musisz mu literały podać. cout odpowiedniej konwersji ci nie przeprowadzi. Rozwiązaniem jest wcout, które - uwaga - dostałeś w pierwszym poście i ustawienie odpowiedniego setlocale - różne pod Windows (.852) i pod Linuksami (np. .UTF-8, bo takie kodowanie konsoli może być - i chyba jest najczęściej - używane). Tylko tutaj jest kolejny problem: Mingw nie ma zaimplementowanego wcout i wstringów, musisz działać na wprintf i wchar_t[].

Ewentualnie to pieprzone kodowanie pliku ustawić na codepage 852 kompilując pod Windows i UTF-8 pod Linuksy.

Jeżeli ktoś ci powiedział, że C++ jest łatwo-przenośne to kłamał.

1
0DFh napisał(a)

Ja zawsze używałem:
setlocale(LC_ALL,"");
Tylko że LC_ALL ma takie skutki uboczne, że ustawia też format czasu, daty, i przestawia separator dziesiętny z kropki na przecinek — a nie zawsze tego chcemy (chociaż teoretycznie powinniśmy ;-)). Jeśli chodzi nam tylko o kodowanie znaków (i sortowanie), to wtedy LC_CTYPE.

Poza tym, "" działa, bo przestawia konsolę na domyślną „okienkową” stronę kodową. Ale nasz plik nie jest w „jakiejś domyślnej” stronie kodowej, tylko konkretnej (CP1250).
Dlatego lepiej podać jawnie ".1250", co zadziała nawet jeśli na danym komputerze normalnie nie ma ustawionego polskiego kodowania.

A jeszcze chyba doszedłem kiedy to nie działa pod XP. Wygląda na to, że zależy to od kompilatora. Program skompilowany pod Visualem działa i pod XP i pod Win7. Program skompilowany GCC (MinGW) prawidłowo zmienia kodowanie w Win7, ale źle w WinXP.

PS. strzelam że winna jest biblioteka msvcrt.dll — mingw korzysta z domyślnej systemowej, visual przynosi własną.

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