[c++] odczyt z pliku tekstowego do stringu a polskie znaki

0

Cześć

Ta petla poprawnie odczytuje z pliku litery i spacje do stringu (kopia), jednak gdy pojawia się polskie znaki, to sa jakies "krzaczki"?
Jak zrobic, by odczytywano poprawnie polskie znaki ?

 
while (FILE.good())
    {
        kopia.resize(10+i);
        
                std::cout<<"*";
        kopia[i]=ch;
        ch=FILE.get();
        ++i;
        
    }
0
kart napisał(a)

Cześć

Ta petla poprawnie odczytuje z pliku litery i spacje do stringu (kopia), jednak gdy pojawia się polskie znaki, to sa jakies "krzaczki"?
Jak zrobic, by odczytywano poprawnie polskie znaki ?

 
while (FILE.good())
    {
        kopia.resize(10+i);
        
                std::cout<<"*";
        kopia[i]=ch;
        ch=FILE.get();
        ++i;
        
    }

Ta pętla poprawnie wczytuje kolejne bajty z pliku do stringa. Bajty - nie litery czy spacje. Jeśli proces odwrotny(zapisanie do pliku z tego stringa) się powiedzie to znaczy, że wszystko jest ok - co najwyżej nie potrafisz tego wyświetlić(kodowanie którego używa Twój edytor i kodowanie emulatora termina na którym program uruchamiasz powinny być takie same).

0

a no tak, dziala to dobrze, problem jest w tej funkcji, ktora po wyswietleniu (na koncu w petli) wszystkie polskie znaki zamienia na jakies "krzaczki"

void Huffman::zlicz_liczbe_roznych_znakow() 
{
    using namespace std;

  
    vector<char>::iterator it;
     vector<int>::iterator t;

    liczba_liter=0;
    licznik=0;
 
    while (kopia[licznik])
    {
        
        it = find (znaki.begin(), znaki.end(), kopia[licznik]);

     
        if (it != znaki.end())
        {
            licznik++;
            

            vector<char>::iterator t= it;
            int k = t - znaki.begin();

            ilosc_z[k]+=1;
            continue;
            
        }
        else
        { 
            znaki.push_back(kopia[licznik]);
            ilosc_z.push_back(1);
            ++liczba_liter;
            ++licznik;
           
        }


       
    }
    for ( it=znaki.begin(),t=ilosc_z.begin()  ; it != znaki.end();  it++ ,t++)
              std::cout << (*it) << " => " << (*t)<<endl;   //tu blednie wypisywane sa polskie znaki, gdzies wyzej blad, bo zawartosc stringu jest ok

   

}

z góry dzieki za pomoc

 
0

Jeżeli nie potrzebujesz przeprowadzać żadnych operacji na tekście to wystarczy że Twoja konsola(pewnie cmd.exe?) będzie potrafiła poprawnie zintepretować ciąg bajtów wysyłany na wyjście(std::cout). O ile mnie pamięć nie myli to cmd.exe korzysta domyślnie z kodowania cp850(nie mam teraz jak sprawdzić). Twój edytor zapewne z cp1250. Albo zmień kodowanie w edytorze, albo w cmd.exe(za pomocą "chcp").
Miło by było gdyby używana przez cmd.exe czcionka posiadała polskie znaki ;).

0

ok, pisze pod Ubuntu
ten sam problem wystepuje, gdy kompiluje to przez g++
domyslnie korzystam z netbeans, nie widze tam zadnej opcji do zmiany tego kodowania

ale czyli tak, czy siak kod tej funkcji jest ok, a problemem jest kodowanie.

w dalszej czesci kodu bede musial wrzucac to wszystko do kolejki prorytetowej, a pozniej do kopca (tak sie zastanawiam, czy ten problem z wyswietlaniem znaku nie bedzie mi to utrudnial, jak np. bede chcial dodać do kolejki litere 'ł' ?)

0

jednak, wewnatrz tego wektora cos jest nie tak, bo taki kod:

if (znaki[5] == 'ł')
        std::cout << "siema dziala
    else
        std::cout << "NIE"; 

zwraca NIE, wiec albo nie rozumiem o co chodzi w tym kodowaniu (co pisales) albo ta funkcja dziala zle ?

0

Jeśli piszesz pod Ubuntu to zapewne domyśle kodowanie edytora to UTF8. Sprawdź kodowanie konsoli(nie korzystam z Netbeans) i sprawdź czy używana przez Ciebie czcionka posiada polskie znaki.

kart napisał(a)

jednak, wewnatrz tego wektora cos jest nie tak, bo taki kod:

if (znaki[5] == 'ł')
        std::cout << "siema dziala
    else
        std::cout << "NIE"; 

zwraca NIE, wiec albo nie rozumiem o co chodzi w tym kodowaniu (co pisales) albo ta funkcja dziala zle ?

Jeśli kompilujesz z użyciem g++(a pewnie tak jest) to powinieneś dostać następujące ostrzeżenia:

warning: multi-character character constant
warning: overflow in implicit constant conversion

Oznacza to tyle że każesz mu traktować "ł" jako typ char(jednobajtowy znak). Podczas gdy w UTF-8 "ł" będzie więcej niż jednym bajtem.

<code = cpp>std::string = "Łania";

/* std::string[0] = jedna część litery "Ł".
std::string[1] = druga część litery "Ł".*/


Możesz to łatwo sprawdzić przez string.size(), które nie zwróci Ci liczby znaków, tylko bajtów.

Jeśli chcesz porównywać wielobajtowe znaki korzystaj z std::wchar.
0

ok, to chyba na pewno to kodowanie
ale to jest dziwne, chce sobie napisac program kompresujacym huffmanem pliki tekstowe i kurcze nawet jak znajde jakies kodowanie, aby moc u siebie poprawnie wykonac program, to z innym plikiem tekstowym ( z innycm kodowaniem) bedzie to juz dzialac zle

Dosyc to wszytko problematyczne i utrudnia przenosnosc :D

0

ok, po zmianie na wchar_t

ł jest rozponawane jako -59 i -126

netbeans ma podobno kodowanie utf, wiec pewnie stad ten problem...

mam rozumiec, ze np. po zmianie IDE na takie uzywajace kodowania jak g++ wszystko bedzie dzialac ok ?

0
kart napisał(a)

ok, po zmianie na wchar_t

ł jest rozponawane jako -59 i -126

netbeans ma podobno kodowanie utf, wiec pewnie stad ten problem...

mam rozumiec, ze np. po zmianie IDE na takie uzywajace kodowania jak g++ wszystko bedzie dzialac ok ?

Kodowanie dla g++ nie ma znaczenia. Kodowanie edytora i konsoli/terminala z jakiego korzystasz musi być takie samo.

0

sprawdzilem kodowania
terminal - utf8
netbeans - utf8
plik txt - utf8

wiec wszystko ok, a dalej program nie wyswietla polskich znakow

zastapile tez (char - > wchar_t i string na wstring)

dlaczego tak sie dzieje ?

0
kart napisał(a)

sprawdzilem kodowania
terminal - utf8
netbeans - utf8
plik txt - utf8

wiec wszystko ok, a dalej program nie wyswietla polskich znakow

zastapile tez (char - > wchar_t i string na wstring)

dlaczego tak sie dzieje ?

wstring jest Ci potrzebny tylko jeśli masz zamiar przeprowadzać jakieś operacje na tekście.

Co do problemu, jedyne co mi przychodzi na myśl to brak odpowiedniej czcionki.

0

ok, dzieki za rady,
moze jeszcze ktos ma jakis pomysł ?
a co ciekawe identyczna sytuacja jest na Windowsie, pod Code::Blocks :)

0
kart napisał(a)

ok, dzieki za rady,
moze jeszcze ktos ma jakis pomysł ?
a co ciekawe identyczna sytuacja jest na Windowsie, pod Code::Blocks :)

Code::Blocks na pewno nie korzysta z dosowego kodowania z którego korzysta cmd.exe. W netbeans może porównaj takiego samego std::stringa wczytanego z pliku i wprowadzonego z klawiatury.

0

@const_variable, czy Tobie się przypadkiem konsola z cmd.exe nie pomyliła?

0
deus napisał(a)

@const_variable, czy Tobie się przypadkiem konsola z cmd.exe nie pomyliła?

A w cmd.exe nie można ustawić kodowania? Co konkretnie masz na myśli?

0

Jeśli konsola/terminal/whatever śmiga w unikodzie, a tekst jest w ansi, to musisz ustawić *locale *strumienia.

0

@const_variable, to mam na myśli, że cmd.exe to tylko aplikacja konsolowa, jest mniej/więcej tym samym dla Batcha czym python.exe dla Pythona. Nie ma nic wspólnego z istnieniem konsoli jako takiej.

0
0x666 napisał(a)

Jeśli konsola/terminal/whatever śmiga w unikodzie, a tekst jest w ansi, to musisz ustawić *locale *strumienia.

ok, tylko jak to zrobic? nie wiem dokladnie o co to chodzi :)

0
deus napisał(a)

@const_variable, to mam na myśli, że cmd.exe to tylko aplikacja konsolowa, jest mniej/więcej tym samym dla Batcha czym python.exe dla Pythona. Nie ma nic wspólnego z istnieniem konsoli jako takiej.

Wybacz, ciężko mi znaleźć lepsze określenie dla czegoś co MS nazwał command interpreter.

kart napisał(a)
0x666 napisał(a)

Jeśli konsola/terminal/whatever śmiga w unikodzie, a tekst jest w ansi, to musisz ustawić *locale *strumienia.

ok, tylko jak to zrobic? nie wiem dokladnie o co to chodzi :)

http://www.cplusplus.com/reference/std/locale/locale/

0

@const_variable, napiszę szerzej bo widać nie rozumiesz. Interpreter poleceń to tylko... interpreter poleceń. Cmd.exe zazwyczaj nie bierze udziału w odpalaniu programów (chyba, że coś skorzysta np. z funkcji system), to zwyczajna aplikacja konsolowa, chcp zaś również zwykły program, który korzysta z tego, że konsola bywa (bo nie zawsze jest) dziedziczona. Okna konsoli, strumienie itd. tworzy i zarządza nimi csrss.exe (w Windows 7 część z tego przejął conhost.exe). Pisanie w tym wątku czegokolwiek o cmd.exe jest całkowicie bez sensu.

0
deus napisał(a)

@const_variable, napiszę szerzej bo widać nie rozumiesz. Interpreter poleceń to tylko... interpreter poleceń. Cmd.exe zazwyczaj nie bierze udziału w odpalaniu programów (chyba, że coś skorzysta np. z funkcji system), to zwyczajna aplikacja konsolowa, chcp zaś również zwykły program, który korzysta z tego, że konsola bywa (bo nie zawsze jest) dziedziczona. Okna konsoli, strumienie itd. tworzy i zarządza nimi csrss.exe (w Windows 7 część z tego przejął conhost.exe). Pisanie w tym wątku czegokolwiek o cmd.exe jest całkowicie bez sensu.

Dzięki, zawsze dobrze się czegoś dowiedzieć :). Niezmiernie rzadko korzystam z systemu windows(z cmd jeszcze rzadziej). Że chcp jest programem to się domyśliłem, ale o csrss.exe conhost.exe nie wiedziałem.
Cmd to zwyczajnie ułomna powłoka zamknięta w prostym GUI?

0

Cmd.exe to program jak każdy inny, (interaktywny) interpreter Batcha, sam w sobie wcale nie posiada GUI. Za to, czy proces domyślnie dostaje konsolę odpowiada odpowiednia flaga w nagłówku, loader przy okazji rejestrowania innych rzeczy w csrss.exe przesyła informację o konieczności przydzielenia konsoli. Ten systemowy proces zajmuje się wszystkimi oknami konsol (w tym tworzy dla nich pętle komunikatów) itd. - dlatego okno konsoli nie dostosowuje się do stylu ustawionego u użytkownika. Nawet jeżeli proces nie posiada odpowiedniej flagi to może sobie zawołać AllocConsole, na każdy proces może przypadać maksymalnie jedna. Zazwyczaj są one dziedziczone, stąd chcp modyfikuje odziedziczoną konsolę, zmiany pozostają po jego zakończeniu, wpływając na zachowanie procesu-rodzica i kolejnych procesów potomnych.

Co do ułomności to bym nie przesadzał, musi trzymać kompatybilność wsteczną, masz alternatywę w postaci PowerShella przecież, fenomenalnego shella.

0
deus napisał(a)

Cmd.exe to program jak każdy inny, (interaktywny) interpreter Batcha, sam w sobie wcale nie posiada GUI. Za to, czy proces domyślnie dostaje konsolę odpowiada odpowiednia flaga w nagłówku, loader przy okazji rejestrowania innych rzeczy w csrss.exe przesyła informację o konieczności przydzielenia konsoli. Ten systemowy proces zajmuje się wszystkimi oknami konsol (w tym tworzy dla nich pętle komunikatów) itd. - dlatego okno konsoli nie dostosowuje się do stylu ustawionego u użytkownika. Nawet jeżeli proces nie posiada odpowiedniej flagi to może sobie zawołać AllocConsole, na każdy proces może przypadać maksymalnie jedna. Zazwyczaj są one dziedziczone, stąd chcp modyfikuje odziedziczoną konsolę, zmiany pozostają po jego zakończeniu, wpływając na zachowanie procesu-rodzica i kolejnych procesów potomnych.

Co do ułomności to bym nie przesadzał, musi trzymać kompatybilność wsteczną, masz alternatywę w postaci PowerShella przecież, fenomenalnego shella.

Dzięki wielkie, za jasne wytłumaczenie :).
PowerShell jest strasznie powolny(choć może to tylko moje subiektywne odczucie). Osobiście na windowsie korzystam z basha dostarczonego wraz z gitem.

Pozdrawiam!

0

Jest wolny na starcie, bo to aplikacja .NET - musi się rozruszać, swego czasu sporo z niego korzystałem nawet na tak zabytkowym sprzęcie jak PIII 1GHz + 384MB. Fakt, że nawet po pewnym czasie potrafi czasem trochę przyciąć, ale rekompensują to ogromne możliwości.

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