C++ string::compare och eller operator?

Permalänk
Medlem

C++ string::compare och eller operator?

Hej,
Håller fortfarande på att lära mig C++.

Jag tycker det är så gött med en" och eller operator" (skrivs || ) för integer så jag undrar om det finns för string med.

Någon som vet, jag har inte kunnat hitta något annat än string::compare som bara jämför två variablar med varandra.

Visa signatur

Asus P8P67 Deluxe B3 | Intel i7-2600k@3,4GHz | 16 GB Corsair Vengeance LP 1600Mhz CL9 | Asus GTX 580 Matrix@900Mhz | Corsair Force GT 120GB | WD Caviar Black 1TB | Corsair 850 AX | Fractal Design R4 | Dell u2410 | Qpad MK-80 | QPad 5K

CITERA FÖR SVAR!

Permalänk
Medlem

Operatorn || är ju operatorn för logisk disjunktion i C++, och returnerar sant om ett eller båda av argumenten är sanna. Den är alltså egentligen bara definierad för bool i C++, men går att använda med int eftersom C++ automatiskt typkonverterar int till bool och tolkar det som att 0 är falskt medan alla andra värden är sanna.

Operatorn är inte definierad för strängar i C++, eftersom en sträng i sig inte har någon logisk mening. Vill du kunna använda || så får du själv bestämma vad en sann eller falsk sträng är. Om du t.ex. vill kolla om en av strängarna innehåller något så kan du t.ex. använda "!str1.empty() || !str2.empty()".

Permalänk
Medlem
Skrivet av perost:

Operatorn || är ju operatorn för logisk disjunktion i C++, och returnerar sant om ett eller båda av argumenten är sanna. Den är alltså egentligen bara definierad för bool i C++, men går att använda med int eftersom C++ automatiskt typkonverterar int till bool och tolkar det som att 0 är falskt medan alla andra värden är sanna.

Operatorn är inte definierad för strängar i C++, eftersom en sträng i sig inte har någon logisk mening. Vill du kunna använda || så får du själv bestämma vad en sann eller falsk sträng är. Om du t.ex. vill kolla om en av strängarna innehåller något så kan du t.ex. använda "!str1.empty() || !str2.empty()".

Det bör nog funka, men hur kodar jag det. T.ex. hur ska jag göra här:

#include <iostream> #include <string> using namespace std; int main () { string answer; string solution = "apa"; string solution2 = "Apa"; cout <<"Djur som gillar bananer" << endl; cin >> answer; if () // Här ska den säga "sant" om answer == solution || solution2. Hur gör jag? cout << "sant"; else cout << "fel"; char f; cin >> f; return 0; }

Visa signatur

Asus P8P67 Deluxe B3 | Intel i7-2600k@3,4GHz | 16 GB Corsair Vengeance LP 1600Mhz CL9 | Asus GTX 580 Matrix@900Mhz | Corsair Force GT 120GB | WD Caviar Black 1TB | Corsair 850 AX | Fractal Design R4 | Dell u2410 | Qpad MK-80 | QPad 5K

CITERA FÖR SVAR!

Permalänk
Medlem

Du får skriva:

if(answer == solution || answer == solution2)

Notera att du måste göra samma med int, det är stor skillnad på tex. "i == 3 || i == 5", "i == 3 || 5" eller "i == (3 || 5)". "i == 3 || i == 5" är sant om i är 3 eller 5. "i == 3 || 5" är alltid sant oavsett värdet på i eftersom den kollar om i är 3, eller 5 (alltså inte om i är 5, utan bara 5), vilket blir sant eftersom 5 är sant. "i == (3 || 5)" är samma sak som "i == 1", eftersom "3 || 5" är sant vilket blir 1 som int.

Permalänk
Medlem
Skrivet av perost:

Du får skriva:

if(answer == solution || answer == solution2)

Notera att du måste göra samma med int, det är stor skillnad på tex. "i == 3 || i == 5", "i == 3 || 5" eller "i == (3 || 5)". "i == 3 || i == 5" är sant om i är 3 eller 5. "i == 3 || 5" är alltid sant oavsett värdet på i eftersom den kollar om i är 3, eller 5 (alltså inte om i är 5, utan bara 5), vilket blir sant eftersom 5 är sant. "i == (3 || 5)" är samma sak som "i == 1", eftersom "3 || 5" är sant vilket blir 1 som int.

Jag måste ha tabbat mig tidigare och skrivit något som

if(answer == solution || solution2)

vilket du påpekar. Tack så mycket. Jag krånglade till det en del när jag inte kunde få det att funka.

Skrivet av perost:

vilket blir sant eftersom 5 är sant. "i == (3 || 5)" är samma sak som "i == 1", eftersom "3 || 5" är sant vilket blir 1 som int.

Menar du med detta att om man då skriver:

i == 3 || 5

så är det samma som:

i = 3 || 5

?

Förresten, när man kan använda samma operators på string som integer (tex. ==, ||, && ect). Varför finns då t.ex. string::compare. Känns lite krångligare att använda?

t.ex.

if (solution.compare (answer) == 0)

Visa signatur

Asus P8P67 Deluxe B3 | Intel i7-2600k@3,4GHz | 16 GB Corsair Vengeance LP 1600Mhz CL9 | Asus GTX 580 Matrix@900Mhz | Corsair Force GT 120GB | WD Caviar Black 1TB | Corsair 850 AX | Fractal Design R4 | Dell u2410 | Qpad MK-80 | QPad 5K

CITERA FÖR SVAR!

Permalänk
Medlem
Skrivet av Lillem4n:

Menar du med detta att om man då skriver:

i == 3 || 5

så är det samma som:

i = 3 || 5

?

Nej, "i = 3 || 5" skulle tilldela 3 till i, och hela uttrycket skulle sedan bli sant. Hela poängen var att oavsett vad som står till vänster om || så kommer hela uttrycket alltid att vara sant, eftersom 5 är sant.

Skrivet av Lillem4n:

Förresten, när man kan använda samma operators på string som integer (tex. ==, ||, && ect). Varför finns då t.ex. string::compare. Känns lite krångligare att använda?

t.ex.

if (solution.compare (answer) == 0)

==-operatorn och string::compare har inte samma beteende. == returnerar bara sant eller falskt beroende på om strängarna är lika eller inte. string::compare returnerar 0 om strängarna är lika, annars ett positivt eller negativt heltal som talar om vilken av strängarna som är "störst", se t.ex. här för mer information.

Notera också att du inte använder || och && på andra datatyper än bool (om man inte överlagrat dem för någon typ dvs.). || och && opererar endast på booleska uttryck, dvs. uttryck som är antingen sanna eller falska. Den enda anledningen till att du kan använda dem på int är att C++ automatiskt typkonverterar int till bool.

Permalänk
Medlem
Skrivet av perost:

Nej, "i = 3 || 5" skulle tilldela 3 till i, och hela uttrycket skulle sedan bli sant. Hela poängen var att oavsett vad som står till vänster om || så kommer hela uttrycket alltid att vara sant, eftersom 5 är sant.

==-operatorn och string::compare har inte samma beteende. == returnerar bara sant eller falskt beroende på om strängarna är lika eller inte. string::compare returnerar 0 om strängarna är lika, annars ett positivt eller negativt heltal som talar om vilken av strängarna som är "störst", se t.ex. här för mer information.

Notera också att du inte använder || och && på andra datatyper än bool (om man inte överlagrat dem för någon typ dvs.). || och && opererar endast på booleska uttryck, dvs. uttryck som är antingen sanna eller falska. Den enda anledningen till att du kan använda dem på int är att C++ automatiskt typkonverterar int till bool.

Tack för förklaringen

Visa signatur

Asus P8P67 Deluxe B3 | Intel i7-2600k@3,4GHz | 16 GB Corsair Vengeance LP 1600Mhz CL9 | Asus GTX 580 Matrix@900Mhz | Corsair Force GT 120GB | WD Caviar Black 1TB | Corsair 850 AX | Fractal Design R4 | Dell u2410 | Qpad MK-80 | QPad 5K

CITERA FÖR SVAR!

Permalänk
Medlem

Värt att notera också att || och && är lata operatorer när de opererar på bools, alltså att de bara evaluerar de uttryck som behöver evalueras (avbryter vid första true i en ||-kedja och första false i en &&-kedja). Om man överlagrar || eller && blir de INTE lata, utan funktionsanropet operator &&(A a, B b) kommer ske, alltså evalueras BÅDA uttrycken.

Just på grund av den semantiken brukar man rekommendera att man inte överlagar de operatorerna.

Visa signatur

void@qnet
teeworlds, stålverk80, evil schemer, c, c++
Languages shape the way we think, or don't.

Permalänk
Medlem
Skrivet av jdv:

utan funktionsanropet operator &&(A a, B b) kommer ske, alltså evalueras BÅDA uttrycken.

Det var bra förklarat men jag hängde inte riktigt med på denna biten. Kan ni förtydliga?

Visa signatur

Asus P8P67 Deluxe B3 | Intel i7-2600k@3,4GHz | 16 GB Corsair Vengeance LP 1600Mhz CL9 | Asus GTX 580 Matrix@900Mhz | Corsair Force GT 120GB | WD Caviar Black 1TB | Corsair 850 AX | Fractal Design R4 | Dell u2410 | Qpad MK-80 | QPad 5K

CITERA FÖR SVAR!

Permalänk
Medlem

Om du skriver if(func1() && func2()) så kommer func2 bara anropas om func1 returnerar falskt. Om du däremot ar överlagrat operator&& för returtyperna så kommer det bli följande: if(operator&&(func1(), func2())) vilket innebär att func2 alltid anropas. Det kan ställa till med problem om man inte vet om att överlagringen finns och antar att den vanliga oöverlagrade &&-operatorn används.

Var mest ett sidospår på diskussionen.

Visa signatur

void@qnet
teeworlds, stålverk80, evil schemer, c, c++
Languages shape the way we think, or don't.

Permalänk
Medlem
Skrivet av jdv:

Om du skriver if(func1() && func2()) så kommer func2 bara anropas om func1 returnerar falskt. Om du däremot ar överlagrat operator&& för returtyperna så kommer det bli följande: if(operator&&(func1(), func2())) vilket innebär att func2 alltid anropas. Det kan ställa till med problem om man inte vet om att överlagringen finns och antar att den vanliga oöverlagrade &&-operatorn används.

Var mest ett sidospår på diskussionen.

Det är bra att du tog upp det. Jag är extremt färsk på c++ så det är sådana problem som jag kan få utan att veta varför.

Tack för förklaringen

Visa signatur

Asus P8P67 Deluxe B3 | Intel i7-2600k@3,4GHz | 16 GB Corsair Vengeance LP 1600Mhz CL9 | Asus GTX 580 Matrix@900Mhz | Corsair Force GT 120GB | WD Caviar Black 1TB | Corsair 850 AX | Fractal Design R4 | Dell u2410 | Qpad MK-80 | QPad 5K

CITERA FÖR SVAR!