kilopierogow Temat założony przez niniejszego użytkownika |
[C++] Ify na tablicy char » 2016-12-03 01:33:29 Witam ponownie, To jeden z algorytmów nad którym pracuję. Użytkownik wpisuje wielokrotność 4 znakowej komendy w postaci [1-5][1-5]![litera(tu w)] Oczywiście po poprawnym wpisaniu powinien wyświetlić się komunikat, co jeszcze mi się nie zdarzyło. Jakieś sugestie? Pozdrawiam. #include <iostream> #include <iomanip> #include <cstdlib>
using namespace std;
int main() { int wielkosc = 7; char komenda[ 6 ]; for( int i = 0; i < 6; i++ ) komenda[ i ] = '0'; cin.clear(); cin.getline( komenda, 6 ); for( int i = 0; i < 6 && komenda[ i ] != '\0'; i++ ) { int dobrze = 0; if( komenda[ i ] == 'w' || komenda[ i ] == 'W' ) { if( komenda[ i - 1 ] == '!' ) { char wspolrzedna = komenda[ i - 2 ]; int wsp = wspolrzedna - '0'; if( wsp > 0 && wsp <( wielkosc - 1 ) ) { char wspolrzedna2 = komenda[ i - 3 ]; int wsp2 = wspolrzedna2 - '0'; if( wsp2 > 0 && wsp2 <( wielkosc - 1 ) ) { if( komenda[ i - 4 ] == ' ' || komenda[ i - 4 ] == '/0' ) { cout << "spelnione"; dobrze = 1; } } } } } } return 0; }
|
|
carlosmay |
» 2016-12-03 08:40:10 if( komenda[ i - 1 ] == '!' )
|
Tutaj masz wyjście poza tablicę dla i == 0 i w każdym zagnieżdżeniu instrukcji if jest coraz gorzej. Zamiast męczyć się z tablicą char zastosuj std::string lub kontener std::vector . Użytkownik wpisuje wielokrotność 4 znakowej komendy w postaci [1-5][1-5]![litera(tu w)] |
Rozwiń to. Podaj przykład, jakie dane wpisujesz. Jeśli w kodzie jest aż tyle zagnieżdżeń instrukcji if , kod wymaga przemyślenia. Ogólnie drugie zagnieżdżenie jest już słabo czytelne, a co dopiero pięć. Sprawdzeniem poprawności współrzędnych (komendy) powinna zająć się osobna funkcja. zamień na bool czyDobrze = false; . To jest dużo czytelniejsze. |
|
mokrowski |
» 2016-12-03 13:07:01 Jeśli już chcesz _koniecznie_ robić to na tablicy znaków, proponuję for(...) realizować od ostatniego znaku komendy i w pętli sprawdzić czy: (ostatni znak to 'w' lub 'W') oraz (przed_ostatni znak to '!'). Pobranie współrzędnych będzie wtedy związane wyłącznie z przetworzeniem znaków na wartość int. Jeśli jednak nie chcesz popełniać błędów jakie masz w tym kodzie (wyjście poza tablicę), możesz to zrobić tak... taki kod "na szybko" ... #include <string> #include <iostream>
using namespace std;
string czytaj_komende() { string komenda; cin >> komenda; return komenda; }
bool to_komenda_w( const string & komenda ) { if( komenda.size() < 4 ) { cerr << "Komenda ma nieodpowiednią długość!" << endl; return false; } auto komenda_riter = komenda.rbegin(); auto ostatni_znak = * komenda_riter; auto przed_ostatni_znak = *( ++komenda_riter ); return(( ostatni_znak == 'w' ) or( ostatni_znak == 'W' ) ) and( przed_ostatni_znak == '!' ); }
using wspolrzedne_t = pair < int, int >;
wspolrzedne_t daj_wspolrzedne( const string & komenda ) { auto wartosc = stoi( komenda ); return make_pair( wartosc / 10, wartosc % 10 ); }
bool spelnia_warunek_w( const wspolrzedne_t & wspolrzedne ) { return( wspolrzedne.first <= 5 ) and( wspolrzedne.first >= 1 ) and( wspolrzedne.second <= 5 ) and( wspolrzedne.second >= 1 ); }
int main() { auto komenda = czytaj_komende(); if( to_komenda_w( komenda ) ) { if( spelnia_warunek_w( daj_wspolrzedne( komenda ) ) ) cout << "spełnione" << endl; } }
|
|
kilopierogow Temat założony przez niniejszego użytkownika |
» 2016-12-03 14:51:09 Przykłady komend : 13!d 25!A 32!s itd. 4 znak to litery "wWaAsSdD", komendy użytkownik rozdziela pojedynczą spacją. 1-5 akurat w tym przypadku, ale wcześniej wielkosc=7 jest zmienną (ograniczyłem to na potrzeby fragmentu). Ogólny wzór to cyfry mają być z przedziału od zera(bez zera) do wielkosc-1(bez tej wartosci). Dla wielkosc=7 jest to 1-5.
Co do odp. od mokrowski, nie mogę posługiwać się "auto" (podstawowy Code Blocks bez C++11), chociaż kod mi się podoba (ale wywala error przy kompilacji 'stoi' was not declared in this scope (?)). Dzięki za odpowiedzi. Pozdrawiam. |
|
mokrowski |
» 2016-12-03 16:05:44 Oj tam.. mówisz i masz.. zgodne z kompilatorami "przed c++11" #include <string> #include <iterator> #include <iostream>
using namespace std;
string czytaj_komende() { string komenda; cin >> komenda; return komenda; }
bool to_komenda_w( const string & komenda ) { if( komenda.size() < 4 ) { cerr << "Komenda ma nieodpowiednią długość!" << endl; return false; } string::const_reverse_iterator komenda_riter = komenda.rbegin(); char ostatni_znak = * komenda_riter; char przed_ostatni_znak = *( ++komenda_riter ); return(( ostatni_znak == 'w' ) or( ostatni_znak == 'W' ) ) and( przed_ostatni_znak == '!' ); }
typedef pair < int, int > wspolrzedne_t;
wspolrzedne_t daj_wspolrzedne( const string & komenda ) { int wartosc = atoi( komenda.c_str() ); return make_pair( wartosc / 10, wartosc % 10 ); }
bool spelnia_warunek_w( const wspolrzedne_t & wspolrzedne ) { return( wspolrzedne.first <= 5 ) and( wspolrzedne.first >= 1 ) and( wspolrzedne.second <= 5 ) and( wspolrzedne.second >= 1 ); }
int main() { string komenda = czytaj_komende(); if( to_komenda_w( komenda ) ) { if( spelnia_warunek_w( daj_wspolrzedne( komenda ) ) ) cout << "spełnione" << endl; } }
|
|
kilopierogow Temat założony przez niniejszego użytkownika |
» 2016-12-03 16:21:24 Nie wiem o co chodzi ale tak jak w twojej pierwszej wersji wywalało mi stoi was not declared, tak teraz wywala mi atoi was not declared. Kompiluje ci się to normalnie? |
|
jankowalski25 |
» 2016-12-03 16:37:11 atoiBrakuje #include <cstdlib> . Ewentualnie: #include <sstream>
int atoi( const char * str ) { std::istringstream in( str ); int i = 0; in >> i; return i; } |
|
mokrowski |
» 2016-12-03 16:43:27 No nic... nie ma to nie ma. Dołącz <cstdlib>. Jak dalej problem to .. proszę oto naiwne (ale skuteczne) obejście .. :-/ wspolrzedne_t daj_wspolrzedne( const string & komenda ) { return make_pair( komenda.c_str()[ 0 ] - '0', komenda.c_str()[ 1 ] - '0' ); }
|
|
« 1 » 2 |