[C++] Problem z zamianą polskich znaków w programie

0

Witam wszystkich na forum. Piszę w sprawie mojego programu.
Ogólnym celem programu jest: wczytanie pytania użytkownika, połączenie programu z internetem, ściągnięcie 10 pierwszych stron dla zadanego pytania, usunięcie znaczników htmla, przeszukanie pozostałego tekstu w celu znalezienia odpowiedzi na pytanie i zwrócenie jej.
Większość mojego programu działa poprawnie, ale problem zaczyna się w miejscu kiedy ze ściągniętych kodów źródłowych stron (10 najlepszych wyników) zapisanych w plikach txt chce zamienić polskie znaki na odpowiedniki (ą na a itp) w celu puźniejsze analizy tekstu.
Moja funkcja zamiany polskich znaków na zwykłe w pliku txt działa dobrze gdy sam stworze plik i zapisze w nim jakiś przykładowy tekst. Gdy funkcja próbuje zamienić znaki w pliku wygenerowanym przez inny fragment kodu pliku funkcja usuwa polskie znaki ale nie wstawia w ich miejsce odpowiedników.
Poniżej zamieszczę kod funkcji:

Czy ktoś mógłby mi pomóc ? Proszę o jakieś wskazówki lub wskazanie funkcji ewentualnie jakiś fragment kodu który mógłby mi pomóc.

Poniżej podaje kod. Proszę, nie wnikajcie w strukturę, kod miał po prostu działać :)

 
void zamien_polskie_znaki_plik(){ //zamienia polskie znaki na zwykłe
	fstream f,k;
	string bufor, slowo;
	
	f.open("dane_poprawione.txt");  // tu można zmienić na dowolny plik txt wynik zamiany znaków i tak bedzie zapisany do pliku linijke niżej
	k.open("dane.txt",fstream::out); // tu nic nie zmieniać bo sie nazwy popiepszą
	
	while(!f.eof()){
		f >> bufor;
		const char* bufor_char = bufor.c_str();
		int bufor_size = bufor.length();

		for(int i=0;i<bufor_size;i++){
			if( bufor_char[i]=='a' || bufor_char[i]=='b' || bufor_char[i]=='c' || bufor_char[i]=='d' || bufor_char[i]=='e' || 
				bufor_char[i]=='f' || bufor_char[i]=='g' || bufor_char[i]=='h' || bufor_char[i]=='i' || bufor_char[i]=='j' || 
				bufor_char[i]=='k' || bufor_char[i]=='l' || bufor_char[i]=='m' || bufor_char[i]=='n' || bufor_char[i]=='o' || 
				bufor_char[i]=='p' || bufor_char[i]=='r' || bufor_char[i]=='s' || bufor_char[i]=='t' || bufor_char[i]=='u' || 
				bufor_char[i]=='q' || bufor_char[i]=='w' || bufor_char[i]=='x' || bufor_char[i]=='y' || bufor_char[i]=='v' || 
				bufor_char[i]=='z' || bufor_char[i]=='A' || bufor_char[i]=='B' || bufor_char[i]=='C' || bufor_char[i]=='D' || 
				bufor_char[i]=='F' || bufor_char[i]=='G' || bufor_char[i]=='H' || bufor_char[i]=='I' || bufor_char[i]=='J' || 
				bufor_char[i]=='K' || bufor_char[i]=='L' || bufor_char[i]=='M' || bufor_char[i]=='N' || bufor_char[i]=='O' || 
				bufor_char[i]=='P' || bufor_char[i]=='R' || bufor_char[i]=='S' || bufor_char[i]=='T' || bufor_char[i]=='U' || 
				bufor_char[i]=='Q' || bufor_char[i]=='W' || bufor_char[i]=='X' || bufor_char[i]=='Y' || bufor_char[i]=='V' || 
				bufor_char[i]=='Z' || bufor_char[i]=='E' || bufor_char[i]=='.' || bufor_char[i]==',' || bufor_char[i]=='!' ||
				bufor_char[i]=='?' || bufor_char[i]=='”' || bufor_char[i]==':' || bufor_char[i]==';' || bufor_char[i]=='(' ||
				bufor_char[i]==')' || bufor_char[i]=='[' || bufor_char[i]==']' || bufor_char[i]=='{' || bufor_char[i]=='}' ||
				bufor_char[i]=='"'){
					slowo.push_back(bufor_char[i]);
					continue;
			} else {
				switch(bufor_char[i]){
					case 'ą' : slowo.push_back('a'); break;
					case 'ć' : slowo.push_back('c'); break;
					case 'ę' : slowo.push_back('e'); break;
					case 'ł' : slowo.push_back('l'); break;
					case 'ó' : slowo.push_back('o'); break;
					case 'ś' : slowo.push_back('s'); break;
					case 'ń' : slowo.push_back('n'); break;
					case 'ź' : slowo.push_back('z'); break;
					case 'ż' : slowo.push_back('z'); break;
					case 'Ą' : slowo.push_back('A'); break;
					case 'Ć' : slowo.push_back('C'); break;
					case 'Ę' : slowo.push_back('E'); break;	
					case 'Ł' : slowo.push_back('L'); break;	
					case 'Ó' : slowo.push_back('O'); break;
					case 'Ś' : slowo.push_back('S'); break;
					case 'Ń' : slowo.push_back('N'); break;
					case 'Ź' : slowo.push_back('Z'); break;
					case 'Ż' : slowo.push_back('Z'); break;
				}	
			}
		}
		k << slowo << " ";
	
		slowo.clear();
	}	

	k.close();
	f.close();
	
	cout<<"koniec zamiany znaków"<<endl;
}
0

Tą całą konstrukcję if..else zamień na :

Gdzieś na początku funkcji:

string polskieZnaki = "ąćęłóśńżźĄĆĘŁÓŚŃŻŹ"
string odpowiedniki = "acelosnzzACELOSNZZ"
int iloscZnakow =  sizeof(odpowiedniki) / sizeof(char);

I samego ifa na:

char znak = bufor_char[i];

if (znak >= '  ' && znak <= '~' && znak != '<' && znak != '>')
{
	slowo.push_back(znak);
	continue;
}
else
{
	for (int i = 0; i < iloscZnakow; i++)
	{
		if (znak == polskieZnaki[i])
			slowo.push_back(odpowiedniki[i);
	}
}

Pierwszy if uwzględnia znaki pomiędzy znakami spacji a tyldy, możesz je zobaczyć na asciitable.com z wykluczeniem znaków większości i mniejszości.
Ogółem to dawno w C++ nie robiłem, więc jak by co nie bij. Poza tym nie wiem jak z wsparciem dla znaków polskich, char to był raczej jedno bajtowy więc tylko 256 kombinacji.

0
char toneutral(char ch)
  {
   static char NEU[]="acelnoszzACELNOSZZąćęłńóśżźĄĆĘŁŃÓŚŻŹ",*POL=NEU+18;
   char *ptr=strchr(POL,ch);
   return ptr?*(ptr-18):ch;
  }
 
f>>bufor;
for(int i=0;i<bufor.length();++i) bufor[i]=toneutral(bufor[i]);
k<<bufor<<" ";

Po kiego powtarzać temat ??

0

Odpowiedź Vishera okazała się po prostu lepszą alternatywą mojego rozwiązania (za co dziękuje) lecz problem nadal występuje. Chodzi o to że gdy zamieniam znaki z "normalnym" pliku txt z tekstem jakimś krótkim stworzonym przeze mnie to działa i jest dobrze. Problem jest kiedy mam w pliku txt kod źródłowy jakiejś strony i chce w nim zamienic znaki (już po usunięciu znaczników htmla) to nie zamienia ich tylko po prostu usuwa np: największe --> najwiksze. Nie wiem co może powodować taki problem... Wydaje mi sie że sama funkcja zamiany znaków w takim razie jest poprawna problem tkwi gdzie indziej. Ktoś może ma pomysł gdzie?

0

strony mogą mieć różne kodowanie - utf-8, iso-8859-2, windows 1250 itp., wtedy każda litera jest zapisana jako inny bajt lub bajty. to powoduje, że problem staje się nietrywialny, bo trzeba rozpoznać stronę kodową. chyba, że użyjesz jakichś gotowych funkcji dostępnych poprzez np. google.

np. słowo "różne" w utf-8, które jest stroną kodową 4p, wygląda w przeglądarce prawidłowo, ale jak wkleję je ze znaczkami w iso-8859-2, to będzie wyglądać tak: "róşne" - a takich znaczków nie masz zdefiniowanych w swoim słowniku. zauważ, że w tym przypadku z obu liter robią się dwie...

0

Masz problem z kodowaniem, dlatego standardowe znaki działają, a polskie mają inne kody więc, żaden z ifów nie jest spełniony i znak przepada.
Dowiedz się czym jest kodowanie 8-bitowe, np. ANSI Windows, ISO-ileśtam (html'e lubią być w nich kodowane) oraz UTF-8 i UTF-16. Sprawdź jak koduje znaki twój kompilator.

0

Tak też myślałem ale nie sądziłem że po skopiowaniu tekstu na notatnika kodowanie będzie miało znaczenie. Znamy już problem ale nadal nie mam pomysłu na rozwiązanie...

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