• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Wzorce regularne - problem w pętli

0 głosów
1,227 wizyt
pytanie zadane 8 maja 2016 w C i C++ przez pawel00 Nowicjusz (240 p.)

Napisałem taki krótki programik, który wyciąga miasto, ulice itd. z tekstu i nam je wypisuje. Pętla wykonuje się 10 razy, ale problem jest tego rodzaju, że już za drugim razem podając adres program nie wyświetla mi tylko 1szego parametru (ulicy) , czyli mojego podwzorca. Gdzie jest problem?

#include <iostream>
#include <string>
#include <regex> 
using namespace std; 

int main()
{
    string tekst;
    regex wzorzec("(\\w*)\\s(\\d+-\\d+)\\s(\\w*)\\s(\\d*)");
    cout << "Podaj adres w formie <ulica kod(np.70-777), miasto, numer"<<endl;
   

	for(int i=0;i<10;i++){
		getline(cin,tekst);
        smatch wynik;
		
		if(regex_search(tekst, wynik, wzorzec)){
			try{
		//	for( int i=0; i<wynik.size()-4; ++i){
        cout << "Ulica: " << wynik[1] <<endl;    
		cout << "Kod: " << wynik[ 2 ] <<endl;    
		cout << "Miasto: " << wynik[3 ] <<endl; 
		cout << "Numer: " << wynik[4 ] <<endl;
		}
			catch(...){
            std::cout << "Zly wzorzec.\n";  
		}
		}

		//else
	//		cout<<"Niepoprawny adres"<<endl;
        cin >> tekst;

	}
}

 

komentarz 8 maja 2016 przez draghan VIP (106,230 p.)
cout << "Ulica: " << wynik[1] <<endl;    
cout << "Kod: " << wynik[ 2 ] <<endl;    
cout << "Miasto: " << wynik[3 ] <<endl; 
cout << "Numer: " << wynik[4 ] <<endl;

Nie powinieneś indeksować od zera?

1
komentarz 8 maja 2016 przez adrian17 Mentor (355,220 p.)
Nie, poczytaj doumentację smatcha.
komentarz 8 maja 2016 przez draghan VIP (106,230 p.)

Racja. yes

3 odpowiedzi

+1 głos
odpowiedź 8 maja 2016 przez adrian17 Mentor (355,220 p.)

Zabierz ten "cin >> tekst;", to on Ci miesza czytając ulicę.

Przy okazji, jest coś takiego jak raw literal:

regex wzorzec(R"((\w*)\s(\d+-\d+)\s(\w*)\s(\d*))");

 

komentarz 8 maja 2016 przez pawel00 Nowicjusz (240 p.)
A jak najlepiej zrealizować pkt2.?  Zapytamy się użytkownika co poda teraz, użytkownik wpisze ulica, no i co dalej? Jak ten kod przekształcić, aby po wpisaniu hasła ulica była możliwość wpisania ulicy do odpowiedniego wzorca?
komentarz 8 maja 2016 przez adrian17 Mentor (355,220 p.)

jeśli już wiesz, że teraz poda ulicę, nie potrzebujesz żadnego wzorca.

if (nastepne == "ulica") {
    getline(cin, ulica);
} else if (nastepne == "telefon") {
    cin >> telefon;
} (etc)

 

komentarz 9 maja 2016 przez pawel00 Nowicjusz (240 p.)
Ale regex wrzorzec zostaje taki sam czy jak? Nie bardzo rozumiem.
komentarz 9 maja 2016 przez pawel00 Nowicjusz (240 p.)
string tekst;
	string nastepne;
	string a;
    regex wzorzec("(\\w*)\\s(\\d+-\\d+)\\s(\\w*)\\s(\\d*)");
	regex wzorzeculicamiasto("\\w*");
	regex wzorzeckod("\\d+-\\d+");
	regex wzorzecnumer("\\d*");
    cout << "Podaj adres w formie <ulica kod(np.70-777), miasto, numer"<<endl;
   smatch wynik;
   smatch wynik1;
   smatch wynik2;
   smatch wynik3;

		for(int i=0;i<4;i++){
		cout<<"Co najpierw?";
		cin>>a;
		nastepne=a;
		if (nastepne == "ulica") {
    getline(cin, nastepne);
	cin>>nastepne;
	if(regex_search(nastepne, wynik, wzorzeculicamiasto))
	cout << "Ulica: " << wynik[0] <<endl;
} else if (nastepne == "kod") {
    getline(cin, nastepne);
	cin>>nastepne;
	if(regex_search(nastepne, wynik1, wzorzeckod))
		cout << "Kod: " << wynik1[0] <<endl;  
}
		else if (nastepne == "miasto") {
    getline(cin, nastepne);
	cin>>nastepne;
	if(regex_search(nastepne, wynik2, wzorzeculicamiasto))
		cout << "Miasto: " << wynik2[0] <<endl; 
}
		else if (nastepne == "numer") {
    getline(cin, nastepne);
	cin>>nastepne;
	if(regex_search(nastepne, wynik3, wzorzecnumer))
		cout << "Numer: " << wynik3[0] <<endl;
}

		}
cout<<wynik[0]<<wynik1[0]<<wynik2[0]<<wynik3[0]
}

Mam coś takiego, wypisywać po kolei wypisuje, ale już linijki cout<<wynik[0]<<wynik1[0]<<wynik2[0]<<wynik3[0] nie wypisuje poprawnie. Dlaczego? Dobrze jest to zrobione?

komentarz 9 maja 2016 przez pawel00 Nowicjusz (240 p.)
edycja 9 maja 2016 przez pawel00

Tamte pytanie wyżej jest nieważne. Pojawił się inny problem, a mianowicie - mam ustalone we wzorcu ulicę jako

(\\w*\\d+) - jak teraz przy wypisaniu tego podwzorca wyciągnąć tylko adres?  Czyli w konsoli podaje adres np. Nowatorska 6 i chcę z tego podwzorca wyciągnąć 6 - jest to możliwe?: jak?
#include <iostream>
#include <string>
#include <regex>
using namespace std; 

int main()
{
    string tekst;
    regex wzorzec("(\\w*\\d+)\\s(\\d+-\\d+)\\s(\\w*)");
    regex wzorzec2("\\w*\\d+)\\s(\\w*)\\s(\\d+-\\d+)");
 //   regex wzorzec3("(\\w*)\\s(\\w*\\d+)\\s(\\d+-\\d+)");
 //   regex wzorzec4("(\\w*)\\s(\\d+-\\d+)\\s(\\w*\\d+)");
 //   regex wzorzec5("(\\d+-\\d+)\\s(\\w*)\\s(\\w*\\d+)");
//	regex wzorzec6("(\\d+-\\d+)\\s(\\w*\\d+)\\s(\\w*)");

	
	for(int i=0;i<10;i++){
		getline(cin,tekst);
        smatch wynik;		
		if(regex_search(tekst, wynik, wzorzec)){	
			//string temp=wynik[1];

		//	std::string::size_type sz; 
		//	 float temp2 = std::stof (wynik[1],&sz);
        cout << "Ulica: " << wynik[1] <<endl;    
		cout << "Kod: " <<  wynik[2] <<endl;    
		cout << "Miasto: " << wynik[3] <<endl; 
	//	cout << "Numer: " << temp2 <<endl;
		}
		if(regex_search(tekst, wynik, wzorzec2)){	
			 cout << "Ulica: " << wynik[1] <<endl;    
		cout << "Kod: " <<  wynik[3] <<endl;    
		cout << "Miasto: " << wynik[2] <<endl; 
	}
		//else
	//		cout<<"Niepoprawny adres"<<endl;

	}
}

 

0 głosów
odpowiedź 10 maja 2016 przez pawel00 Nowicjusz (240 p.)

Mam taki kod:

#include <iostream>
#include <string>
#include <regex>
using namespace std; 
 
int main()
{
    string tekst;
    regex wzorzec("(\\w*\\d+)\\s(\\d+-\\d+)\\s(\\w*)");
    regex wzorzec2("\\w*\\d+)\\s(\\w*)\\s(\\d+-\\d+)");
 //   regex wzorzec3("(\\w*)\\s(\\w*\\d+)\\s(\\d+-\\d+)");
 //   regex wzorzec4("(\\w*)\\s(\\d+-\\d+)\\s(\\w*\\d+)");
 //   regex wzorzec5("(\\d+-\\d+)\\s(\\w*)\\s(\\w*\\d+)");
//  regex wzorzec6("(\\d+-\\d+)\\s(\\w*\\d+)\\s(\\w*)");
 
     
    for(int i=0;i<10;i++){
        getline(cin,tekst);
        smatch wynik;       
        if(regex_search(tekst, wynik, wzorzec)){    
            //string temp=wynik[1];
 
        //  std::string::size_type sz; 
        //   float temp2 = std::stof (wynik[1],&sz);
        cout << "Ulica: " << wynik[1] <<endl;    
        cout << "Kod: " <<  wynik[2] <<endl;    
        cout << "Miasto: " << wynik[3] <<endl; 
    //  cout << "Numer: " << temp2 <<endl;
        }
        if(regex_search(tekst, wynik, wzorzec2)){   
             cout << "Ulica: " << wynik[1] <<endl;    
        cout << "Kod: " <<  wynik[3] <<endl;    
        cout << "Miasto: " << wynik[2] <<endl; 
    }
        //else
    //      cout<<"Niepoprawny adres"<<endl;
 
    }
}

I teraz w tym momencie we wzorcu mam ustawioną ulicę jako (\\w*\\d+) - jak teraz przy wypisaniu tego podwzorca wyciągnąć tylko cyfry?  Czyli w konsoli podaje adres np. Nowatorska 6 i chcę z tego podwzorca wyciągnąć 6 - jest to możliwe?: jak?

 

–1 głos
odpowiedź 8 maja 2016 przez DragonCoder Nałogowiec (36,500 p.)
Tak jak @draghan napisal, musisz pamietac ze gdy programujesz to podajesz liczby po amerykansku nie po europejsku to  jest takze w odcinku z tablicami u Pana Miroslawa. A wiec przesun wszystko o jedno w dol i powinno wszystko chodzic. A nie widze tablicy... Chyba ze jest to smatch... to przepraszam. Osobscie jest poczatkujacym i nie znam tej funkcji
1
komentarz 8 maja 2016 przez draghan VIP (106,230 p.)
Co znaczy "podajesz liczby po amerykansku nie po europejsku"? Słyszę to już tu po raz n-ty i nikt nie potrafi mi podać źródła dla takiego stwierdzenia.
komentarz 8 maja 2016 przez DragonCoder Nałogowiec (36,500 p.)
A jakie zrodlo trzeba podac? Moge sworzyc 2 krotkie programy ktore udowodnia ze numeruje sie od zera po za tym Pan Miroslaw takze to wyjasnia...A wiec odsylam

https://www.youtube.com/watch?v=Rt1HnMdzINo
1
komentarz 8 maja 2016 przez adrian17 Mentor (355,220 p.)

numerujemy nie po europejsku, od jedynki, a po amerykańsku, od zera

...to jest najgłupsze zdanie, jakie jak dotąd widziałem w tych filmikach. Nie mam pojęcia, skąd on w ogóle wymyślił podział na "amerykańskie" i "europejskie" numerowanie.

Dla formalności, możesz spojrzeć na:

https://en.wikipedia.org/wiki/Zero-based_numbering

https://en.wikipedia.org/wiki/Comparison_of_programming_languages_%28array%29#Array_system_cross-reference_list

Pierwszy język z indeksowaniem "europejskim" (przy okazji pierwszy powszechnie używany język programowania), Fortran, powstał w USA, a pierwszy język z indeksowaniem "amerykańskim", BCPL, powstał w Cambridge w Anglii.

komentarz 8 maja 2016 przez DragonCoder Nałogowiec (36,500 p.)
Chodzi o zastosowanie mam to pokazac na przykladzie? Zrobie program ktory wypelnie tablice x[5] ale jak wypisze ze pierwsze jest x[1]...x[4] to sie wykona, ale dla x[5] juz nie... To samo mowi Pan Miroslaw
komentarz 8 maja 2016 przez adrian17 Mentor (355,220 p.)

...ale do czego zmierzasz?

Jeśli mówisz o indeksowaniu smatch (który nie jest tablicą) to wypada żebyś przeczytał jego dokumentację:

http://en.cppreference.com/w/cpp/regex/match_results/operator_at

komentarz 8 maja 2016 przez DragonCoder Nałogowiec (36,500 p.)
Tak tylko moje pytanie brzmialo gdzie jest tablica i chyba ze to jest smatch sam nie znam tej funkcji jestem poczatkujacym... Jesli nie jest to przepraszam za maja zbedna wypowiedz i chetnie przeczytam
komentarz 8 maja 2016 przez adrian17 Mentor (355,220 p.)
Smatch ma przeładowany operator[]:

http://en.cppreference.com/w/cpp/regex/match_results/operator_at

Co oznacza, że można na nim używać [].

(już się z czymś takim spotkałeś, std::string też ma przeładowany [], dzięki czemu może się zachowywać jak tablica)
komentarz 8 maja 2016 przez DragonCoder Nałogowiec (36,500 p.)
A no tak :D kazdy litera jest przechowywana jako osobna komorka w pamieci

Podobne pytania

0 głosów
1 odpowiedź 413 wizyt
pytanie zadane 24 kwietnia 2018 w PHP przez Browarnik123 Użytkownik (830 p.)
0 głosów
0 odpowiedzi 366 wizyt
pytanie zadane 26 lipca 2017 w Inne języki przez Pan_Student Nowicjusz (140 p.)
0 głosów
2 odpowiedzi 966 wizyt
pytanie zadane 10 czerwca 2023 w JavaScript przez andrzej.polak Nowicjusz (220 p.)

93,765 zapytań

142,721 odpowiedzi

323,373 komentarzy

63,358 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...