logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Porównywanie stringów w C++: dlaczego mój kod nie działa?

Jakub17 04 Cze 2016 11:11 5814 35
Najlepsze odpowiedzi

Dlaczego mój kod w Arduino/C++ zapala diodę niezależnie od odpowiedzi modułu Bluetooth i jak poprawnie sprawdzać, czy odebrany napis zawiera oczekiwany fragment?

Dioda zapala się, bo w warunku masz zbędny średnik po `if(command == odpowiedz);`, więc instrukcja `if` jest pusta, a blok wykonuje się zawsze [#15719928][#15720151][#15721183] Po usunięciu tego błędu pamiętaj, że porównanie dokładne z `"OK"` nadal może nie działać, jeśli w odebranym stringu są znaki końca linii lub inne dodatkowe znaki, np. `"OK\r\n"` [#15721215][#15723514] Zamiast porównywać cały napis, sprawdzaj, czy string zawiera szukany fragment, np. metodą `find` albo `indexOf` [#15721246][#15723033][#15721358] Trzeba też odbierać dane do znaku CR albo CR+LF, żeby nie rozcinać komunikatu w złym momencie i zachować synchronizację [#15724453] Jeśli budujesz warunek na `find`, nie porównuj wyniku do `false` w sposób, który miesza typy; użyj wyniku metody zgodnie z jej zwracanym typem [#15723174]
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA
  • #1 15719847
    Jakub17
    Poziom 6  
    Posty: 484
    Ocena: 15
    Witam, piszę tu nie wiem który raz odnośnie programowania w C i C++

    Tym razem mam taki kodzik:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Kod polega na zapalaniu diody gdy otrzymana odpowiedź modułu bluetooth na komendę AT pokrywa się z tą zadaną na początku ("odpowiedz")
    Nie wiem dlaczego dioda zapala się bez względu na to jaką otrzymam "odpowiedz". Nawet jak wpisuje byle co w monitor portu szeregowego to bluetooth zwraca w odpowiedz ERROR(0) czyli że komenda jest nie obsługiwana a dioda i tak się zapala. W moim założeniu dioda powinna się zapalić kiedy otrzymam odpowiedz w której zawarty będzie adres urzadzenia sparowanego z modułem czyli "98ff:d0:bbd84d". Sparowania dokonywałem komendą AT+BIND a odpowiedz na nią wygląda tak: "+BIND:98ff:d0:bbd84d" (szukana odpowiedź to substring ale mniejsza o to, w kodzie jakoś to zrobię). Nie chce żeby dioda się zapalała jak wpisuje byle jaką komendę tylko chcę aby się zapalała jak uzyskam konkretną odpowiedz z modułu. Ktoś potrafi powiedzieć dlaczego to źle działa?
  • REKLAMA
  • #2 15719928
    Konto nie istnieje
    Konto nie istnieje  
  • #3 15720023
    Jakub17
    Poziom 6  
    Posty: 484
    Ocena: 15
    Fakt, jestem niechlujny ale to dlatego że mam dużo teraz na głowię i piszę w biegu.
    Nie piszę dla przyjemności tylko z przymusu, nie znam podstaw języka i nie mam czasu czytać książki o programowaniu bo jestem zajęty nauką czegoś innego ale muszę wykonać projekt...

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Zrobiłem tak. Dioda po otrzymaniu komendy odpowiedzi "OK" się nie zapala. W drugiej linii jest constant String "odpowiedź". Tylko tak się zastanawiam czy po konwersji na char "command" nie powinien być tablicą.
  • REKLAMA
  • #4 15720050
    Konto nie istnieje
    Konto nie istnieje  
  • #6 15720074
    JacekCz
    Poziom 42  
    Posty: 8670
    Pomógł: 760
    Ocena: 1463
    Jakub17 napisał:
    Witam, piszę tu nie wiem który raz odnośnie programowania w C i C++


    Tak na marginesie, po pierwsze pytanie nie dotyczy standardu C++ tylko dialektu Arduino, a tam string pisze się z wielkiej litery. Piotr ma rację, błąd jest widoczny jak kobyła.


    Jakub17 napisał:
    ...piszę tu nie wiem który raz odnośnie programowania w C i C++

    Fakt, ... po drugie nie mogę zaakceptować uczenia się języków programowania z forum.

    Dodano po 1 [minuty]:

    xoree napisał:
    A nie prościej :

    if( strcmp( str1, str2 ) == 0 )
    {
    coś tam coś tam
    }
    else
    {
    coś tam coś tam 2
    }


    Myślę że nie. Nawet jesli to jest dialekt Arduino, jak już zaczęliśmy z dialektowym Stringiem to się trzymajmy.

    Dodano po 2 [minuty]:

    Piotrus_999 napisał:


    Jakub17 napisał:
    Fakt, jestem niechlujny ale to dlatego że mam dużo teraz na głowię i piszę w biegu.


    To nie pisz :) Bo masz wtedy jeszcze więcej na głowie.

    Możesz mieć tez inne błedy - ale po tej linijce analizowanie reszty mija się z celem.


    Kolejny programista dyslektyk, który w cywilu jest dyslektykiem czy dysgrafikiem ale podobno pisze niezawodny kod? Brak podstawowej staranności ...
  • REKLAMA
  • #8 15720098
    JacekCz
    Poziom 42  
    Posty: 8670
    Pomógł: 760
    Ocena: 1463
    xoree napisał:
    W Arduino strcmp działa poprawnie.
    (kilka razy używałem).


    Ja nie mówię że nie działa. Wszędzie działa *) Tylko ze mieszanie jest w złym stylu.
    Na przykład gdybyś w tym stylu przenosił np kod na pececie z epoki znaków 8bit do unikodu by było ciężko, a tylko na własną prośbę.

    *) nawiasem mówiąc tam po drodze jeszcze po cichu zachodzą konwersje itd. Nie dziwiłbym się jakby twój sposób, pozornie tak rdzenny "C" był wolniejszy o kilka taktów czy kilka bajtów chwilowego zużycia stosu, w porównaniu do konsekwentnego Arduino.
  • #9 15720151
    Konto nie istnieje
    Konto nie istnieje  
  • #10 15720157
    JacekCz
    Poziom 42  
    Posty: 8670
    Pomógł: 760
    Ocena: 1463
    Piotrus_999 napisał:
    @JacekCz & inny - problem lezy gdzie indziej - nie trzeba mącić człowiekowi. Cokolwiek wpisze w nawiasie w swoim if-ie to i tak nie zadziała.


    agree :)
  • #12 15721183
    Konto nie istnieje
    Konto nie istnieje  
  • #13 15721190
    Jakub17
    Poziom 6  
    Posty: 484
    Ocena: 15
    Chodzi oczywiście o ten średnik... Jestem idiotą. Dopiero teraz to zauważyłem.

    Choć mimo że poprawiłem błąd to i tak nie działa:/
    Przynajmniej dioda nie zapala się jak wpisze cokolwiek...

    Aktualnie tak wygląda mój kod:

    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #14 15721215
    Konto nie istnieje
    Konto nie istnieje  
  • #15 15721221
    Jakub17
    Poziom 6  
    Posty: 484
    Ocena: 15
    Mam zaznaczone w terminalu żeby po kazdej komendzie dodawał \r\n

    Mam też taki kod, ale tutaj nic się nie wyświetla nawet jak wpiszę komendę do terminala. A dziwne, bo wydaje mi się że jest wszystko dobrze...

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Ale i tak wolałbym się skupić na kodzie analizowanym poprzednio...
  • #16 15721236
    Konto nie istnieje
    Konto nie istnieje  
  • #18 15721246
    Konto nie istnieje
    Konto nie istnieje  
  • #19 15721353
    Jakub17
    Poziom 6  
    Posty: 484
    Ocena: 15
    Znalazłem na stronie Arduino fajny program do analizy znaków:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    W monitorze portu szeregowego wpisuję: OK

    I uzyskałem następujący raport:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Wygląda na to że miałeś rację. Za OK występują jeszcze dwie spacje.
    Tylko teraz pytanie:

    Czy bluetooth też wysyła to "OK" w takim formacie. Okazuje się że chyba nie, bo wpisałem w kodzie w miejsce dwie spacje po OK i nie działa:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Więc próbowałem ten kod diagnostyczny zaimplementować do programu z tematu:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Problem jest taki:

    Wpisuję "AT" to nie otrzymuje odpowiedzi "OK" a następnie jest ona rozbijana na czynniki pierwsze i analizowana tylko wpisuję AT to mam rozbijane na czynniki pierwsze AT, wpisuje OK - to OK...

    Przy czym komunikat o znakach jest bardzo ubogi bo tylko tyle:

    Kod: text
    Zaloguj się, aby zobaczyć kod


    Piotrus wiesz co tu jest schrzanione?
  • #20 15721358
    Konto nie istnieje
    Konto nie istnieje  
  • Pomocny post
    #21 15723033
    Piotrek1970
    Poziom 18  
    Posty: 273
    Pomógł: 12
    Ocena: 154
    Drogi Jakubie odbierane przez Ciebie znaki po OK też nie są spacjami tylko... zajrzyj do tabeli znaków ASCII gdzie odnajdziesz znaki o wartościach jakie są w linii ASCII value a to wyjaśni Twój błąd lub posłuchaj Piotrus_999 i zacznij szukać opisu funkcji, która sprawdza czy string1 zawiera string2.

    Miłej nauki
  • #22 15723138
    Jakub17
    Poziom 6  
    Posty: 484
    Ocena: 15
    Piotrus czy o to Ci chodziło?

    Założyłem pesymistycznie że nie znajdzie "OK" no i nie znalazł - dostaję komunikat "no find" zaraz po "wydrukowaniu" na monitorze portu szeregowego "OK" po wpisaniu komendy "AT"

    Jaki są według Ciebie dalsze kroki?


    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #23 15723174
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #24 15723312
    ditomek
    Poziom 22  
    Posty: 590
    Pomógł: 24
    Ocena: 230
    Już nie mogę tego czytać...

    zmienna_liczbowa=String_zawierajacy_szukany_fragment.indexOf("szukany_fragment");

    Zmienna_liczbowa jest większa od zera (a dokładnie to wskazuje na miejsce w przeszukiwanym stringu) kiedy zawiera on szukany fragment.

    Podstawy Arduino bez problemu dostępne w Google
  • #25 15723452
    Jakub17
    Poziom 6  
    Posty: 484
    Ocena: 15
    Poprawiłem i dupa....

    Sprawdziłem w tabeli ASCII kody znaków: 10 i 13 http://www.ascii-code.com/

    Okazuje się że są to znaki kontrolne \r\n. Próbowałem na kilka sposobów i bez rezultatu.....

    Co ciekawe jak w monitorze portu szeregowego ustawię opcję "brak zakończenia linii" to w ogóle nie działa kiedy wpisuję komendę np. AT\r\n. Dopiero jak zaznaczę "zarówno NL jak i CR" i wpisuję AT to pojawia się reakcja. Zatem prawdopodobnie teraz tu leży problem ale nie wiem jak go rozwiązać. Nie wiem czemu karetka i nowa linia tutaj nie działa;/

    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #26 15723476
    ditomek
    Poziom 22  
    Posty: 590
    Pomógł: 24
    Ocena: 230
    Nie rozumiem tu czegoś.
    do zmiennej command zapisujesz odebrane znaki,
    później zmienna comman wystawiasz na port szeregowy,
    ZERUJESZ
    i w pustym stringu chcesz coś znaleźć....
  • #28 15723514
    ditomek
    Poziom 22  
    Posty: 590
    Pomógł: 24
    Ocena: 230
    W stringu który odbierasz szukasz czegoś takiego
    String odpowiedz = "OK\r\n";
    Czyli OK+CR+LF
    Dlaczego dziwisz się ze jak usuniesz w terminalu wysyłanie tych znaków to porównanie nie działa?

    dopisz sobie gdzieś zeby po kazdej próbie przeszukania tego stringu na port został wysłane dwie zmienne: ta której szukasz i ta W której szukasz, Wtedy będziesz miał przynajmniej pewność ze w stringach masz to co powinno być[/code]
  • #29 15723627
    Konto nie istnieje
    Konto nie istnieje  
  • #30 15723675
    JacekCz
    Poziom 42  
    Posty: 8670
    Pomógł: 760
    Ocena: 1463
    Piotrus_999 napisał:
    Jakub17 napisał:
    mySerial.find("OK");
    if(mySerial.find("OK")==false)


    przerażasz mnie. Zaczynam wątpić czy to zadanie znalezienia stringu w stringu jest dla Ciebie wykonalne.


    Mnie też.

    Widzę że w czasie weekendu wątek się w ilości sztuk wypowiedzi rozwinął (w jakości i pozytywnym rozwoju ku osiągnięciu celu nie bardzo)
    Dodał bym to i owo merytorycznie, ale to nie ma sensu.

    Proponuję zamkniecie z braku postępu.

Podsumowanie tematu

✨ W dyskusji poruszono problem porównywania stringów w kodzie C++ używanym w kontekście Arduino, szczególnie w interakcji z modułem Bluetooth HC-06. Użytkownik miał trudności z poprawnym porównywaniem odpowiedzi z urządzenia, co prowadziło do braku reakcji na komendy AT. Wskazano na błędy w kodzie, takie jak niepoprawne użycie średnika w instrukcji warunkowej oraz konieczność uwzględnienia znaków kontrolnych (CR, LF) w porównaniach. Uczestnicy dyskusji sugerowali użycie metod klasy String, takich jak `indexOf`, aby sprawdzić, czy odebrany string zawiera oczekiwaną odpowiedź. Ostatecznie, po poprawkach, użytkownik zauważył, że kod działa poprawnie, gdy odpowiedź zawierała znaki końca linii.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA