Tinker Temat założony przez niniejszego użytkownika |
Modyfikowanie tekstu i sprawdzanie jego długości - jak użyć wielokrotnie metody find » 2017-06-14 21:29:36 Witam wszystkich. Aktualnie przerabiam rozdział 28 kursu. Próbowałem rozwiązać zadanie domowe w trochę inny sposób niż policzenie pozycji każdego znaku i "obrobienie ich" metodami stringa, ale napotkałem pewien problem. Długo szukałem przyczyny, dla której kod przestaje się wywoływać i ustaliłem, że każdy blok kodu, jeżeli umieszczony na samym początku funkcji, wywołuje się w konsoli, ale program "zatrzymuje się" przy następnym bloku. Nie do końca rozumiem zapis size_t b = sTekst.find( "<b>" ); na początku każdego bloku kodu, ale zauważyłem, że nie może być on powtarzany w taki sposób jak to zrobiłem, jednocześnie, gdy usuwałem tę linie z bloków, otrzymywałem błąd, np "spacja was not declared in this scope". Podpowie ktoś jak to poprawnie napisać? Myślałem o rozbiciu tego na 3 oddzielne funkcje, ale trochę bym się oddalił od narzuconego sposobu rozwiązania. Wrzucam kod poniżej: #include <iostream> #include <string>
using namespace std;
string konwertuj( string & sTekst ) { string sWynik; { size_t b = sTekst.find( "<b>" ); do { size_t b = sTekst.find( "<b>" ); if( b != string::npos ) { sTekst.erase( b, 3 ); cout << sTekst << endl; sTekst.insert( b, "[b]" ); cout << sTekst << endl; } } while( b != string::npos ); } { size_t bSlash = sTekst.find( "</b>" ); do { size_t bSlash = sTekst.find( "</b>" ); if( bSlash != string::npos ) { sTekst.erase( bSlash + 4, 4 ); sTekst.insert( bSlash, "[/b]" ); cout << sTekst << endl; } } while( bSlash != string::npos ); } { size_t spacje = sTekst.find( " " ); do { size_t spacje = sTekst.find( " " ); if( spacje != string::npos ) { sTekst.erase( spacje, 2 ); cout << sTekst << endl; } } while( spacje != string::npos ); } sWynik = sTekst; return sWynik; } int main() { string tekst = "<b>to jest </b> testowy napis <b>:)"; cout << konwertuj( tekst ) << endl; cout << tekst << endl; return 0; }
|
|
pekfos |
» 2017-06-14 22:03:37 size_t b = sTekst.find( "<b>" ); do { size_t b = sTekst.find( "<b>" ); } while( b != string::npos );
|
|
Tinker Temat założony przez niniejszego użytkownika |
» 2017-06-14 22:27:10 Czyli cały kod do przeróbki? Bo nie widzę żadnego prostego wyjścia. Napisałem to z użyciem pętli for. Nie do końca mnie to satysfakcjonuje, bo przy tej pętli trzeba było policzyć ile razy dana operacja miała być wykonana. Przy pierwszym rozwiązaniu wszystko było "zautomatyzowane", no prawie... :) |
|
pekfos |
» 2017-06-15 02:21:08 Napisałem to z użyciem pętli for. Nie do końca mnie to satysfakcjonuje, bo przy tej pętli trzeba było policzyć ile razy dana operacja miała być wykonana. |
Open your mind for( size_t off = 0;( off = str.find( "a", off ) ) != std::string::npos; ++off )
Czyli cały kod do przeróbki? |
Nie definiuj dwóch zmiennych, tylko jedną. |
|
Tinker Temat założony przez niniejszego użytkownika |
» 2017-06-19 18:34:22 Dzięki za fajne wytłumaczenie. Wklejam zmodyfikowany kod: #include <iostream> #include <string>
using namespace std;
string konwertuj( string & sTekst ) { string sWynik; for( size_t b = 0;( b = sTekst.find( "<b>", b ) ) != string::npos; b++ ) { sTekst.erase( b, 3 ); cout << sTekst << endl; sTekst.insert( b, "[b]" ); cout << sTekst << endl; } for( size_t bSlash = 0;( bSlash = sTekst.find( "</b>", bSlash ) ) != string::npos; bSlash++ ) { sTekst.erase( bSlash, 4 ); cout << sTekst << endl; sTekst.insert( bSlash, "[/b]" ); cout << sTekst << endl; } for( size_t spacje = 0;( spacje = sTekst.find( " " ) ) != string::npos; ++spacje ) { sTekst.erase( spacje, 2 ); cout << sTekst << endl; } sWynik = sTekst; return sWynik; } int main() { string tekst = "<b>to jest </b> testowy napis <b>:)"; cout << konwertuj( tekst ) << endl; return 0; }
Mam jeszcze kilka pytań: - jak interpretować frazę size_t ? jest to typ danych? jakich? nie kojarzę takiego typu, rozjaśnisz trochę? :) - w ostatniej pętli nie użyłem offsetu w części b, bo gdy się tam znajdował, to program nie usuwał wszystkich podwójnych spacji, wiesz może dlaczego? - no i jeszcze pytanie o inkrementacje w każdej z pętli: czy rzeczywiście zachodzi? |
|
jankowalski25 |
» 2017-06-19 20:26:48 jak interpretować frazę size_t ? |
Zgodnie z Wyszukiwanie frazy w tekście » Klasa std::string - metoda find na razie możesz to w uproszczeniu traktować jako unsigned int , chociaż tak naprawdę zamiast int zwykle jest tam coś innego, zależnie od implementacji (między innymi dlatego, że int może nie zmieścić wszystkiego, jeśli na przykład w programie 64-bitowym będzie zajmował 32 bity) ale w tym momencie może lepiej się w to nie wgłębiaj. Na chwilę obecną wystarczy wiedzieć, że to jest jakiś typ danych, który przechowuje liczbę całkowitą nieujemną. program nie usuwał wszystkich podwójnych spacji, wiesz może dlaczego? |
Przeanalizuj krok po kroku co się stanie, gdy zechcesz usunąć kilka spacji pod rząd. inkrementacje w każdej z pętli: czy rzeczywiście zachodzi? |
Jak wyżej. Zajrzyj do Pętla for » Składnia pętli for. Jeśli dla danego tekstu rozwiniesz prawidłowo pętlę instrukcja po instrukcji (ewentualnie w razie wątpliwości użyjesz debuggera), to zobaczysz krok po kroku co, gdzie i jak się wykonuje. |
|
pekfos |
» 2017-06-19 20:35:34 w ostatniej pętli nie użyłem offsetu w części b, bo gdy się tam znajdował, to program nie usuwał wszystkich podwójnych spacji, wiesz może dlaczego? |
Poza tym, że podany kod do tego nie służył? To był przykład do analizy, nie skopiowania. Moja pętla nie sprawdza 2 razy tego samego miejsca, a gdy ze stringa tylko usuwasz, to się nie sprawdzi. Powinieneś usunąć inkrementację, nie offset. |
|
Tinker Temat założony przez niniejszego użytkownika |
» 2017-06-20 13:33:51 Chcę się upewnić, że dobrze to rozumiem. Zostawiając inkrementację, powoduję że, offset w drugim kroku pętli zostanie zwiększony o 1? #include <iostream> #include <string>
using namespace std;
int main() { string sTekst = "bbbb aaaaaa"; for( size_t spacje = 0;( spacje = sTekst.find( "aaa", spacje ) ) != string::npos; spacje++ ) { sTekst.erase( spacje, 3 ); cout << spacje << endl; } return 0; }
|
|
« 1 » |