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

C++ Obiektowo - odc. 2: Porównanie zmiennych

+1 głos
71 wizyt
pytanie zadane 27 listopada 2021 w C i C++ przez KubaM Nowicjusz (130 p.)

Cześć,

natrafiłem na problem w 2 odcinku Obiektowego C++.

Program w instrukcji warunkowej if() nie jest w stanie porównać dwóch zmiennych typu std::string przy użyciu operatora ==. 

Jedna ze zmiennych jest wczytywana z pliku .txt, a druga wczytywana za pomocą std::cin>> . 

Zawartość zmiennych wyświetlonych na ekran z użyciem std::cout<< jest taka sama (np. "c" oraz "c").

Nie znalazłem działającego rozwiązania tego problemu, próbowałem użyć funkcji .compare() - bezskutecznie.

Co może być istotne - korzystam z Xcode w systemie macOS.

void Pytanie::sprawdz()
{
   if(odpowiedz==poprawna)
   {
      punkt=1;
   }
   else punkt=0;
}

Proste pytanie - co jest nie tak?

1 odpowiedź

+1 głos
odpowiedź 27 listopada 2021 przez Wiciorny Mędrzec (196,660 p.)
edycja 27 listopada 2021 przez Wiciorny

Bo stringi nie porównuje się operatorem "==" porównania, ten operator sprawdza referencje- adres w pamięci, czyli tam gdzie jest zapisany obiekt, a nie to czy jest on równy - jako literał. 
Stąd dwa różne obiekty jako string mające ten sam literał, mają inny adres w pamięci

do porównania stringów służy "compare np"

https://www.cplusplus.com/reference/string/string/compare/

They compare equal -> jeśli są równe zwrócone zostanie 0 ... dlaczego u Ciebie nie zadziała? Bo takie porównanie jak niżej zwróci zero, a if (0) -> oznacza false

if(odpowiedz.compare(poprawna))

i o ile kod jest poprawny to zadziała, w wyżej opisany sposób dla równych znaków zwraca wartości całkowite opisane w dokumentacji tutaj dla równych 0,  dlatego wrzuć jak wyglądają twoje zmienne :), i wrzuć resztę kodu programu 

więc należy to zapisać, zapisując w ten sposób jeśli są równe-> będą zwracać 0 więc warunek 0 == 0 jest prawdziwy 

a samo if(0) jest fałszem, bo 0 -> jako boolean to fałsz 

if(odpowiedz.compare(poprawna) ==0 )

Pamiętaj że wczytując znaki- nie wczytujesz stringa, a CHAR stąd to nie jest to samo 

1
komentarz 29 listopada 2021 przez j23 Mędrzec (169,300 p.)
Właściwy, czyli taki, w którym znaki końca linii są poprawne dla systemu, na którym kompilujesz program.

Notepad++ ma opcję zmiany znaków końca linii.
komentarz 30 listopada 2021 przez KubaM Nowicjusz (130 p.)
Falstart, program jednak nie działa poprawnie, prawidłowo odczytuje 4 pierwsze odpowiedzi, a ostatnią zapisaną w ostatniej linii tekstu w pliku odczytuje błędnie.

Dodatkowo, cofnąłem się do kodu z odcinka 7. podstawowego kursu C++, gdzie pisaliśmy ten quiz nie obiektowo, wtedy program działał prawidłowo, dla rozszerzeń pliku .txt oraz .rtf.

Natomiast aktualnie tamten kod również nie działa, więc jest to zastanawiające, musiałem po drodze coś namącić - nie jestem w stanie doszukać się błędu.

Sprawdzałem kodowanie tekstu - plik UTF-8, kompilator (Xcode) UTF-8, okazało się, że w Xcode można również zmieniać "Line Endings" znaki końca linii na: Unix/MacOS, Classic MacOS oraz Windows, próbowałem wszystkich 3 wersji, jednak program nadal nie działa.

Proszę o podpowiedzi, gdzie mogę szukać problemu, program odczytywał poprawnie odpowiedzi z klawiatury i porównywał z pobranymi z pliku, teraz nie jest to możliwe...
komentarz 30 listopada 2021 przez j23 Mędrzec (169,300 p.)

a ostatnią zapisaną w ostatniej linii tekstu w pliku odczytuje błędnie.

jeśli plik był robiony w notatniku windowsowym, sprawdź, czy ostatnia linia zawiera znak końca linii - w Windowsie \r\n to de facto komenda drukarki nakazująca powrót wózka z głowicą na początek i przewinięcie papieru o jedną linię w dół, dlatego ostatnia linia w plikach windowsowych nie ma EOL-a.

komentarz 1 grudnia 2021 przez KubaM Nowicjusz (130 p.)

Masz rację, ostatnie wyrażenie zawiera znak \r\n.

Wciąż nie mogę pojąć, dlaczego kilka tygodni temu wszystko działało, a teraz jest z tym taki problem.

Przypomniałem sobie, że w międzyczasie robiłem update systemu do BigSur 11.6.1 - może to?

Zaktualizowałem również Xcode do najnowszej wersji - to akurat nic nie zmienia w tej kwestii.

Dziwne, że funkcja zmiany znaku końca linii w Xcode nie sprawdza się w tym przypadku.

Aktualnie poradziłem sobie w ten sposób:

if(odpowiedz[0]==poprawna[i][0])
        {
            cout <<"Poprawna odpowiedź! Zdobywasz punkt!"<<endl;
            punkty++;
        }
        else
        {cout<<"Źle! Nie zdobywasz punktu. Poprawna odpowiedź: "<<poprawna[i]<<endl;}

Czyli porównuje ze sobą pierwsze znaki w string'u.

Pytanie, czy jest to najbardziej optymalne rozwiązanie?

Notepad'a ++ nie ma na MacOS, próbowałem użyć programów dos2mac - ale mimo wpisywania komend w terminalu zgodnie z instrukcją nie chciało mi to zadziałać. 

komentarz 2 grudnia 2021 przez j23 Mędrzec (169,300 p.)

Pytanie, czy jest to najbardziej optymalne rozwiązanie?

Od biedy może być. Zastanawia mnie, co tam jeszcze jest w tym stringu. Sprawdzałeś?

Notepad'a ++ nie ma na MacOS

W zasadzie każdy edytor programistyczny powinien mieć taką opcję.

robiłem update systemu do BigSur 11.6.1 - może to?

Ciekawe. Z tego, co wyczytałem, \r jest znakiem końca linii do wersji 9, później jest UNIX-like, czyli \n. Może przekonwertuj plik do \n i zobacz, czy będzie działać bez poprawek w kodzie.

Podobne pytania

0 głosów
3 odpowiedzi 195 wizyt
pytanie zadane 28 grudnia 2018 w PHP przez PWD Nowicjusz (160 p.)
0 głosów
1 odpowiedź 130 wizyt

86,443 zapytań

135,202 odpowiedzi

300,338 komentarzy

57,193 pasjonatów

Motyw:

Akcja Pajacyk

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

Oto dwie polecane książki warte uwagi. Pełną listę znajdziesz tutaj.

...