1programista Temat założony przez niniejszego użytkownika |
poziom 3 rozdział 28 » 2015-10-14 21:35:17 Witam. Mimo że już było to zadanie na forum nie widziałem rozwiązania mojego problemu. Zad. domowe Napisz program, który z podanego łańcucha znaków usunie powtarzające się spacje występujące obok siebie i zastąpi wszystkie znaczniki <b> oraz </b> znacznikami oraz . Tekst, który powstanie w wyniku przeprowadzenia wspomnianych operacji wypisz na ekran. Mój kod jeszcze nie w pełni skończony:
#include<iostream> #include <string> std::string konwertuj( std::string & sTekst ) { std::string sWynik; //TODO: tu nale¿y napisaæ kod realizuj¹cy zadanie size_t pozycja, k; int i=0; pozycja = sTekst.find(" "); do { k=pozycja; pozycja = sTekst.find(" " ,pozycja+1 ); if(k +1== pozycja) sTekst.erase(pozycja,1); i++; }while(/*pozycja != std::string::npos &&*/ i< 200 ); sWynik=sTekst; std::cout<<" pozycja= "<<pozycja<<" pozycja2= "<<k<<" ilosc powt= "<<i; i=0; pozycja=0; do { pozycja = sTekst.find("</b>"); if(pozycja != std::string::npos) { sTekst.insert(pozycja,"[/b]"); sTekst.erase(pozycja+4,4); } i++; }while(pozycja != std::string::npos && i<200); std::cout<<std::endl<<"pozycja= "<<pozycja; return sWynik; } int main() { std::string tekst = "<b>to jest </b> testowy napis <b>:)"; std::cout << konwertuj( tekst ) << std::endl; return 0; }
Musiałem wstawić dodatkowe zmienne "i" aby pętla się zakończyła. Dlaczego zmienna "pozycja" przybiera kosmiczną wartość mimo że pętla się wykona max 200 razy? Dlaczego std::string::npos nie kończy pętli przecież według kursu metoda (w pętli) .find() na obiekcie sTekst przykład: "pozycja = sTekst.find(" " ,pozycja+1 );" zakończy się kiedyś std::string::npos ? |
|
carlosmay |
» 2015-10-14 22:22:27 Musiałem wstawić dodatkowe zmienne "i" aby pętla się zakończyła. |
nie musiałeś, bez i czy z i szukasz poza napisem. Dlaczego zmienna "pozycja" przybiera kosmiczną wartość mimo że pętla się wykona max 200 razy? |
ponieważ następny szukany znak znajduje tak daleko. Dlaczego std::string::npos nie kończy pętli przecież według kursu metoda (w pętli) .find() na obiekcie sTekst przykład: |
kończy, tylko nie w tym miejscu co chcesz. pozycja = sTekst.find(" " ,pozycja+1 );" zakończy się kiedyś std::string::npos |
tak, tylko trzeba odpowiednio szukać. Dobrym dowodem na działanie std::string::npos jest kończenie się programu (nie zapętla się) po usunięciu 'i'. |
|
1programista Temat założony przez niniejszego użytkownika |
» 2015-10-15 16:06:33 Dzięki za odpowiedź. Carlosmay miałeś rację co do usunięcia dodatkowych zmiennych " i " widocznie coś z moim komp. nie tak bo się zawieszał. Poprawiłem kod: #include<iostream> #include <string> std::string konwertuj( std::string & sTekst ) { std::string sWynik; size_t pozycja, k; int i = 0; pozycja = sTekst.find( " " ); do { k = pozycja; pozycja = sTekst.find( " ", pozycja + 1 ); if( k + 1 == pozycja ) sTekst.erase( pozycja, 1 ); i++; } while( i < 200 ); std::cout << " pozycja= " << pozycja << " pozycja2= " << k << " ilosc powt= " << i << std::endl; i = 0; pozycja = 0; do { pozycja = sTekst.find( "<" ); if( pozycja != std::string::npos ) { sTekst.insert( pozycja, "[" ); sTekst.erase( pozycja + 1, 1 ); } i++; } while( pozycja != std::string::npos ); do { pozycja = sTekst.find( ">" ); if( pozycja != std::string::npos ) sTekst.insert( pozycja, "]" ); sTekst.erase( pozycja + 1, 1 ); } while( pozycja != std::string::npos ); std::cout << std::endl << "pozycja= " << pozycja << std::endl << std::endl; sWynik = sTekst; return sWynik; } int main() { std::string tekst = "<b>to jest </b> testowy napis <b>:)"; std::cout << konwertuj( tekst ) << std::endl; return 0; }
Tylko że po usunięciu "i" w warunku while(/*pozycja != std::string::npos && */i< 200); program nie usuwa długich spacji. W drugiej części programu nie wiem dlaczego usuwa mi na początku znak " [ " ? Myślałem że metoda .find() działa tylko na zakresie tekstu zmiennej "sTekst" załóżmy że zmienna "sTekst" ma 100 znaków to zmienna "pozycja" przyjmuje wartości od 0 do 99 a tu "pozycja" wychodzi poza zakres. Jeszcze raz proszę kogoś o wyjaśnienie łopatologiczne ;) jak to z tym jest. |
|
carlosmay |
» 2015-10-15 18:13:26 Strasznie długi i zawiły kod. Masz zredukować wielokrotną spację do jednego znaku. Najłatwiej szukasz podwójnej spacji i usuwasz znak z pozycji 'pozycja'. Następnie uruchamiasz szukanie od 'pozycja'. W ten sposób znajdziesz od razu następne, aż zostanie jedna, którą pominie i przejdzie szukać dalej.
|
|
carlosmay |
» 2015-10-15 18:23:28 pozycja = sTekst.find( " " ); do { k = pozycja; pozycja = sTekst.find( " ", pozycja + 1 ); if( k + 1 == pozycja ) sTekst.erase( pozycja, 1 ); Tutaj szukasz znaku, nic z nim nie robisz i znów szukasz? Zmienna 'k' nie jest ci do niczego potrzebna. Jeśli używasz pętli 'do while' nie musisz szukać przed pętla i myślę, że łatwiej będzie z 'while'. |
|
1programista Temat założony przez niniejszego użytkownika |
» 2015-10-15 20:37:42 Szukam znaku i przypisuję jego pozycję do zmiennej 'k' aby później porównać czy następna spacja jest koło siebie (przy 'k') Zrobię tak jak mi radzisz od razu z podwójnej spacji #include<iostream> #include <string> std::string konwertuj( std::string & sTekst ) { std::string sWynik; size_t pozycja; int i = 0; do { pozycja = sTekst.find( " " ); if( pozycja != std::string::npos ) sTekst.erase( pozycja, 1 ); i++; } while( pozycja != std::string::npos ); sWynik = sTekst; return sWynik; } int main() { std::string tekst = "<b>to jest </b> testowy napis <b>:)"; std::cout << konwertuj( tekst ) << std::endl; return 0; }
Ok działa dzięki.:) Muszę gdzieś doczytać o mechanizmie wyszukiwania metody .find()bo te zmienne pozycja są kosmiczne |
|
carlosmay |
» 2015-10-15 22:03:21 int i = 0; czy zmiennej 'i' do czegoś używasz? sWynik = sTekst; a ten zabieg lepiej dać na początek, żeby pracować na kopii danych. Teraz działasz na oryginale i na koniec robisz kopię zmodyfikowanych danych (możesz od razu zwrócić return sTekst; |
|
« 1 » |