Permalänk

C++ Nybörjare..

Hej! Jag har två frågor och undrar om någon kan svara på detta..
1. Varför spelet "loopar" om när man skriver in till exempel siffror istället bokstäver?

2. Och skriver jag in ex, 0m434 och sedan "Press Enter" så loopar den bara om hela tiden....
cout<<"WELCOME TO MEANMACHINE!"<<endl;
cout<<"(Press 'ENTER' to continue)"<<endl;
cin.get();

Och skriver jag in ex, 0m434 och sedan "Press Enter" så loopar den bara om hela tiden....

#include <iostream>
#include <string>

using namespace std;

int main ()
{
int balance = 0; //Variabel för saldo
int deposit = 0; //Variabel för insättning av pengar
int bet; //Variabel för bet

cout<<"WELCOME TO MEANMACHINE!"<<endl;
cout<<"(Press 'ENTER' to continue)"<<endl;
cin.get();

cout <<"Please make a deposit, 50, 100 or 500."<<endl; //Här gör du din insättning.
cin >> deposit;

while (deposit != 50 && deposit!=100 && deposit!=500) //Insats är inte 50,100,500 (Ny insats)
{
cout<< "Please try again!"<<endl;
deposit = 0;
cin>> deposit;
}

if (deposit == 50 || deposit ==100 || deposit == 500) //Din insats är korrekt.
{
balance = balance+deposit;
cout <<"Your deposit of ("<<deposit<<") suceeded, your balance is ("<<balance<<")."<<endl;

cout <<"(Press 'ENTER' to continue)"<<endl;
cin.get();

}

cout<<""<<endl;

cout <<"Please make a bet! (1-5000)"<<endl; //Insats
cin>>bet;

while (bet > balance) //Insats större än saldo (Nytt bet).
{
cout<<"Invalid bet, your balance is ("<<balance<<")"<<endl;
cin>>bet;
}

while (bet > 5000 || bet < 1 ) //Insats större än 5000 eller mindre än 1 (Nytt bet).
{
cout << "The amount you entered isn't valid, please try again"<<endl;
cin >> bet;
}

if (bet <= 5000 && deposit >= 1) //Insats är 5000 ≤ 1.
{
balance = balance-bet;
cout<<"Your bet is ("<<bet<<") and your balance is now ("<<balance<<")"<<endl;
}

}

Permalänk
Medlem

Vad menar du med loopar om? Jag kan inte C++ själv men tror inte du kan sätta din variabel "deposit" till något annan än heltal eftersom den är en integer..

Visa signatur

Intel i7 2700k@4.3 | Gigabyte Z68X-UD3H-B3 | Gigabyte R9 280X | Fractal Design Define R3 |
Corsair 8GB 1600MHz VENGEANCE | Corsair SSD 120GB Force GT | Templarius Imperator 850W | Corsair Hydro H60 |
BenQ XL2410T | BenQ GL2450 | SteelSeries Siberia v2 | Razer BlackWidow | Zowie EC1

Permalänk
Medlem

Den kommer fastna i första while loopen så länge deposit är skilt ifrån 50, 100 eller 500. Så om du skriver in 0m453 vilket är en sträng så kommer strömmen tolka det som noll eftersom den kommer stanna vid m eftersom det inte är en siffra (rätta mig om jag har fel). Eller menar du att den även fastnar när du skriver in korrekt summa?

Sen behöver du inte kolla om deposit är lika med 50,100 eller 500 efteråt då du redan ser till att den är det i första while loopen.

samt för rad brytning räcker bara std::cout<<std::endl;
Du behöver inte skicka in en tom sträng.

Visa signatur

Dagens ordspråk:
Den som väntar på något gått väntar alltid för länge.

Permalänk

"while (deposit != 50 && deposit!=100 && deposit!=500) //Insats är inte 50,100,500 (Ny insats)
{
cout<< "Please try again!"<<endl;
deposit = 0;
cin>> deposit;
}"
ledsen att jag inte citerar, ska inte den vara en if sats istället?

Visa signatur

Chassi: Cooler Master HAF X 942 CPU: Intel 3770k @ 4.2 Ghz CPU Kylare: Corsair H80 Ram:16 Gig Balistic X 1600 MhzGPU: Sapphire Radeon R9 290X med Arctic Accelero Xtreme MB: MSI Z77A-GD65 PSU: Chieftec Nitro 750w 80+ Bronze SSDer: Crucial M4 64gb + 2st KINGSTON SSDNOW V+200 128gb i Raid 0Hårddiskar: 2st WD Black 1TB i raid 0 + en WD Green 2TB

Permalänk
Skrivet av Nickieponken:

"while (deposit != 50 && deposit!=100 && deposit!=500) //Insats är inte 50,100,500 (Ny insats)
{
cout<< "Please try again!"<<endl;
deposit = 0;
cin>> deposit;
}"
ledsen att jag inte citerar, ska inte den vara en if sats istället?

Han vill nog att den ska fortsätta klaga tills han får en korrekt insättning.

Permalänk
Medlem
Skrivet av Nickieponken:

"while (deposit != 50 && deposit!=100 && deposit!=500) //Insats är inte 50,100,500 (Ny insats)
{
cout<< "Please try again!"<<endl;
deposit = 0;
cin>> deposit;
}"
ledsen att jag inte citerar, ska inte den vara en if sats istället?

Om man har en if sats där istället så kommer den bara köra checken en gång och sen gå vidare. Om man nu vill garantera att deposit endast får ha värderna 50,100 eller 500 så funkar en while sats bättre.

Mitt tips till trådskaparen är att koppla på en debugger och stega igenom programmet och medhjälp av den inspektera variablerna och se vad för värden varje variabel har. Eller iaf skriv ut lite debug utskrifter typ

// Debug print out. #define print_var(str,x) std::cout<<"[Debug]: "<<str<<" "<<#x<<" = "<<x<<std::endl; print_var("before loop", deposit); // will print out "[Debug]: before loop deposit = <some value>" while (deposit != 50 && deposit!=100 && deposit!=500) //Insats är inte 50,100,500 (Ny insats) { print_var("during loop", deposit); cout<< "Please try again!"<<endl; deposit = 0; cin>> deposit; } print_var("after loop", deposit); #undef print_var;

Visa signatur

Dagens ordspråk:
Den som väntar på något gått väntar alltid för länge.

Permalänk
Medlem

Du kan kolla ifall cin misslyckades med input genom funktionen cin.fail() (returnerar true ifall den misslyckades med indata).

Fast i ditt fall är det nog smidigast att lägga till cin.clear() och cin.ignore() för loopen.

while (deposit != 50 && deposit != 100 && deposit != 500) { cout << "Please try again!" << endl; deposit = 0; cin.clear(); cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // för att ignorera alla characters som har "fastnat" i cin cin >> deposit; }

Visa signatur

C>++

Permalänk
Medlem

Det har absolut ingenting med trådskaparens While-loopar eller If-satser. Felet här är att input-bufferten (cin) används fel.

Eftersom mitt svar blir ganska långt, delar jag upp det i att förklara problemet för att sedan ge tips på en lösning.

Problem

Börjar vi från början så ser det ut så här.

cout<<"WELCOME TO MEANMACHINE!"<<endl; cout<<"(Press 'ENTER' to continue)"<<endl; cin.get();

cin.get() kommer endast plocka ett tecken som finns i inputbufferten (cin). Trycker man nu på Enter kommer den förse bufferten med en newline eller linebreak '\n', vilket cin.get() gladeligen plockar upp. Skriver man däremot t.ex. "0m434" så kommer detta också accepteras och gå vidare. Skillnaden nu är att i inputbufferten ligger det "0m434\n", cin.get() kommer endast ta första tecknet, i det här fallet "0" och lämna återstående i bufferten "m434\n".

När vi sen kommer ner till första inmatningen från användaren stöter vi på problem. cin>>deposit kommer läsa första ordet (alla tecken fram till mellanslag eller radbrytning) som finns i inputbufferten. Eftersom våran inputbuffer redan innehåller "m434\n" så kommer cin förstås ta detta. Vilket gör att användaren inte kommer få någon chans att själv mata in ett värde.

cout <<"Please make a deposit, 50, 100 or 500."<<endl; //Här gör du din insättning. cin >> deposit;

Nu har cin läst "m434", den läser inte \n eftersom detta användes som en indikation för att tala om var inmatningen tog slut. Efter detta kommer den tilldela detta värdet till en int, som inte kan hantera något annat än siffror. Vad händer då? Jo, våran int-variabel blir förstås korrupt. När vi sedan går vidare till jämförelsen med en korrupt int-variabel.

while (deposit != 50 && deposit!=100 && deposit!=500) //Insats är inte 50,100,500 (Ny insats) { cout<< "Please try again!"<<endl; deposit = 0; cin>> deposit; }

Så kommer jämförelsen gå sönder eftersom variablen som vi försöker jämföra med är trasig. Vilket sätter loopen ur spel och låter den gå i all evighet.

Lösning

Hur löser vi det då detta? Väldigt enkelt, läs all användarinmatning till strängar och konvertera sedan det på ett säkert sätt till en int. En sträng som tillåter de flesta tecknen som finns har inte ont av ifall användaren trycker på hela tangentbordet samtidigt.

Börjar vi om från början med lite nya exempel kan det se ut så här:

int balance = 0; //Variabel för saldo int deposit = 0; //Variabel för insättning av pengar int bet; //Variabel för bet string userInput = ""; // Variabel för användarens inmatning cout<<"WELCOME TO MEANMACHINE!"<<endl; cout<<"(Press 'ENTER' to continue)"<<endl; getline(cin, userInput);

Det som är nytt här är strängen userInput och getline() istället för get(). getline tillskillnad från get läser hela raden istället för ett tecken. Vilket gör att det inte spelar någon roll ifall användaren hade skrivit en hel uppsats innan denne hade tryckt på enter.

Ifall användaren har matat in något lustigt, t.ex. "0m434" så kommer detta ligga i userInput-variabeln så länge.

Väl vidare i koden kommer vi till nästa del, där användaren ska ange en mängd för sin deposit.

userInput = ""; // Töm variablen från det skräp som kan ha plockats upp tidigare. cout <<"Please make a deposit, 50, 100 or 500."<<endl; //Här gör du din insättning. cin>>userInput; // Läs ett värde (till userInput) // Här kommer det roliga, omvandla din string till en int. deposit = atoi(userInput.c_str()); // Jämför sedan deposit som vanligt. while (deposit != 50 && deposit!=100 && deposit!=500) //Insats är inte 50,100,500 (Ny insats) { cout<< "Please try again!"<<endl; cin>>userInput; // Läs in det nya värdet till userInput igen deposit = atoi(userInput.c_str()); // Konvertera userInput till en int och tilldela deposit denna }

Detta gör att användaren kan skriva vad som helst, sedan sköter atoi en säker omvandlning från string till int. Är strängen fylld med bokstäver, t.ex. "abc319ddad" kommer detta konverteras till värdet 0. Är det däremot ett korrekt heltalsvärde t.ex. "148" så koverteras detta till värdet 148.

Nu bör alltså problemet som uppstod när du skrev in bokstäver istället för siffror vara löst. Förhoppningsvis har jag täckt upp för principen, så med lite skicklighet bör du kunna klura ut vad du behöver för ändringar i resten av koden.

Jag hoppas det här hjälper dig en bit på vägen i alla fall.

Permalänk

Tack för svar allesammans, det jag sökte var precis det #taailyn beskrev precis Alltså det hade inte något med mina loopar att göra utan själva inmatningen från användaren.

Tack för svar taailyn tror det blev lite klarare i huvudet nu

Permalänk

#taailyn

Jag har stött på problem (Se exemplet nedan) varför blir det sådär? Har det något med userInputen att göra? Först tänkte jag att while-looparna var fel, men jag kan inte hitta något fel i dom.

WELCOME TO MEAN MACHINE!
(Press 'ENTER' to continue)

Please make a deposit, 50, 100 or 500.
500
Your deposit of (500) suceeded, your balance is (500).

Please make a bet! (1-5000)
r4r4
The amount you entered isn't valid, please try again
5000
Your bet is (5000) and your balance is now (-4500)

//Koden
userInput = "";
cout <<"Please make a bet! (1-5000)"<<endl; //Insats
cin>>userInput;

bet = atoi(userInput.c_str());

while (bet > balance) //Insats större än saldo (Nytt bet).
{
cout<<"Invalid bet, your balance is ("<<balance<<")"<<endl;
bet=0;
cin>>userInput;
bet= atoi(userInput.c_str());

}

while (bet > 5000 || bet < 1 ) //Insats större än 5000 eller mindre än 1 (Nytt bet).
{
cout << "The amount you entered isn't valid, please try again"<<endl;
bet = 0;
cin>>userInput;
bet = atoi(userInput.c_str());
}

if (bet <= 5000 && deposit >= 1) //Insats är 5000 ≤ 1.
{
balance = balance-bet;
cout<<"Your bet is ("<<bet<<") and your balance is now ("<<balance<<")"<<endl;
}

Permalänk
Medlem
Skrivet av BinaryBard:

#taailyn

Jag har stött på problem (Se exemplet nedan) varför blir det sådär? Har det något med userInputen att göra? Först tänkte jag att while-looparna var fel, men jag kan inte hitta något fel i dom.

WELCOME TO MEAN MACHINE!
(Press 'ENTER' to continue)

Please make a deposit, 50, 100 or 500.
500
Your deposit of (500) suceeded, your balance is (500).

Please make a bet! (1-5000)
r4r4
The amount you entered isn't valid, please try again
5000
Your bet is (5000) and your balance is now (-4500)

//Koden
userInput = "";
cout <<"Please make a bet! (1-5000)"<<endl; //Insats
cin>>userInput;

bet = atoi(userInput.c_str());

while (bet > balance) //Insats större än saldo (Nytt bet).
{
cout<<"Invalid bet, your balance is ("<<balance<<")"<<endl;
bet=0;
cin>>userInput;
bet= atoi(userInput.c_str());

}

while (bet > 5000 || bet < 1 ) //Insats större än 5000 eller mindre än 1 (Nytt bet).
{
cout << "The amount you entered isn't valid, please try again"<<endl;
bet = 0;
cin>>userInput;
bet = atoi(userInput.c_str());
}

if (bet <= 5000 && deposit >= 1) //Insats är 5000 ≤ 1.
{
balance = balance-bet;
cout<<"Your bet is ("<<bet<<") and your balance is now ("<<balance<<")"<<endl;
}

Din felbeskrivning är lite oklar och inläsningen av deposit verkar saknas, men om problemet är att du kan satsa 5000 fast du har bara satt in 500 så beror det på din sista if-sats. Jämför bet med balance istället för med 5000 (du har redan testat att du har ett valid bet i din while loop).

if (bet <= balance)

Permalänk

Aah jag såg det, jag ändrade det nu

WELCOME TO MEAN MACHINE!
(Press 'ENTER' to continue)

Please make a deposit, 50, 100 or 500.
50
Your deposit of (50) suceeded, your balance is (50).

Please make a bet! (min 1)
rtt34t
Your bet is (0) and your balance is now (50)

Men det blir fortfarande såhär, när jag skriver in siffror och bokstäver tillsammans, så genereras det automatiskt till 0? Hur får man det till så att det blir en ogiltigt insats istället för att "insatsen" automatiskt blir 0 om man skulle blanda bokstäver och siffror.

Permalänk
Hedersmedlem
Skrivet av taailyn.:

Efter detta kommer den tilldela detta värdet till en int, som inte kan hantera något annat än siffror. Vad händer då? Jo, våran int-variabel blir förstås korrupt. När vi sedan går vidare till jämförelsen med en korrupt int-variabel.

while (deposit != 50 && deposit!=100 && deposit!=500) //Insats är inte 50,100,500 (Ny insats) { cout<< "Please try again!"<<endl; deposit = 0; cin>> deposit; }

Så kommer jämförelsen gå sönder eftersom variablen som vi försöker jämföra med är trasig. Vilket sätter loopen ur spel och låter den gå i all evighet.

Nja, det stämmer att inläsningen misslyckas, men det händer inte något mystiskt med variabeln. Den behåller typiskt sitt värde eller sätts till 0 (förmodligen är det upp till kompilatortillverkaren att bestämma). Loopen slutar inte att fungera, men däremot kommer "m434" ligga kvar i bufferten och fortsätta gå dåligt att läsa in även vid efterföljande försök (och till råga på allt har felflaggan hos cin blivit satt).

Permalänk
Medlem
Skrivet av BinaryBard:

Aah jag såg det, jag ändrade det nu

WELCOME TO MEAN MACHINE!
(Press 'ENTER' to continue)

Please make a deposit, 50, 100 or 500.
50
Your deposit of (50) suceeded, your balance is (50).

Please make a bet! (min 1)
rtt34t
Your bet is (0) and your balance is now (50)

Men det blir fortfarande såhär, när jag skriver in siffror och bokstäver tillsammans, så genereras det automatiskt till 0? Hur får man det till så att det blir en ogiltigt insats istället för att "insatsen" automatiskt blir 0 om man skulle blanda bokstäver och siffror.

Där du testar för ogiltig insats måste du även testa att den inte är 0 (om det inte är meningen att du skall kunna satsa 0kr, isf blir det lite mer att göra.)

Permalänk

"int balance = 0; //Variabel för saldo
int deposit = 0; //Variabel för insättning av pengar
int bet; //Variabel för bet"

* Onödiga kommentarer
* Gör det finare med mer mellanrum mellan koden och kommentarerna
* Gör det finare med mellanrum mellan // och kommentaren
(programmering är ganska mentalt arbete, så håll programmet fint)

"cout<<"WELCOME TO MEANMACHINE!"<<endl;
cout<<"(Press 'ENTER' to continue)"<<endl;"

Du kan förkorta det till "cout << "WELCOME TO MEANMACHINE!\n(Press 'ENTER' to continue)" << endl;

"cin.get();"

Och hur ser den här funktionen ut? Ser inte du som att du använder ett library som definierar den.

"cout <<"Please make a deposit, 50, 100 or 500."<<endl; //Här gör du din insättning."

Åter igen är koden ganska tydlig så kommentaren är onödig.

Jag vill inte vara respektlös, men koden är ganska jobbig att läsa igenom. Några delar förstår jag inte alls, som:
"cout<<""<<endl;

cout <<"Please make a bet! (1-5000)"<<endl; //Insats"

Som jag förstår det är "cout<<""<<endl;" bara där för att göra en ny rad. Detta är onödigt. Du kan förkorta ner det till:
"cout <<"\nPlease make a bet! (1-5000)"<<endl; //Insats"

Det finns tydligen medlemmar här som lägger ner tid åt att fixa ditt program. Men för din egen skull bör du överge programmet och börja om på nytt.

Programmet har bra struktur, men det verkar mest som att du härmar det du har sett i andra koden istället för att använda dig av programmeringskunskaper.

Så därför undrar jag hur du lär dig programmering. Kollar du på Youtube?
För C++ skulle jag rekommendera Bjorne Stroustrups "Programming: Practice and Principles using C++".
Den är mycket vänlig för de som inte har programmerat förut. Boken lär dig hur du skriver korta, effektiva och simpla koder.

Permalänk

#silvertoaster jag tar gärna emot kritik! Men som sagt (nybörjare) och det antar jag att du också varit inom någon genre någon gång och då tar det lite tid att ha god "kontroll" över det man gör. Men det var skönt att höra att det var någorlunda struktur, sedan går det alltid lite att finslipa.

Jag läser Grundläggande Programmering med C++ på högskolan, och jag har aldrig sysslat med programmering förut, men tycker det är intressant. Böcker ger mig inte så mycket känner jag så jag försöker lära mig väldigt mycket via internet, här förklarar personer det mer så att en vanlig människa förstår

Permalänk

Glad att du har en bra inställning, men jag skulle fortfarande rekonmendera boken. Som jag skrev i mitt förra inlägg är den väldigt vänlig för nybörjare (den är lätt att förstå).

Skickades från m.sweclockers.com

Permalänk

Har skrivit om koden lite. Något du måste använda dig av är en input-loop, alltså while (cin >> variabel)

EDIT: Har lagt till std_lib_facilities, ett library med funktioner. Du behöver dock inte använda den.

Lägg märke till hur den här delen av koden har ändrats:

cin >> deposit;

while (deposit != 50 && deposit!=100 && deposit!=500) //Insats är inte 50,100,500 (Ny insats)
{
cout<< "Please try again!"<<endl;
deposit = 0;
cin>> deposit;
}

#include "../../std_lib_facilities.h"

int main ()
{
int balance = 0;
int deposit = 0;
int bet;

cout<<"WELCOME TO MEANMACHINE!\n(Press 'ENTER' to continue)"<<endl;
cin.get();

cout <<"Please make a deposit of 50, 100 or 500."<<endl;
cin >> deposit;

while (deposit != 50 && deposit!=100 && deposit!=500) //Insats är inte 50,100,500 (Ny insats)
{
cout<< "Please try again!" << endl;
deposit = 0;
cin >> deposit;
}

if (deposit == 50 || deposit ==100 || deposit == 500) //Din insats är korrekt.
{
balance += deposit;
cout <<"Your deposit of ("<<deposit<<") suceeded, your balance is ("<<balance<<").\n(Press 'ENTER' to continue)"<<endl;

cin.get();
}

cout <<"\nPlease make a bet! (1-5000)"<<endl; //Insats

while(cin >> bet)
{

if (bet > balance) //Insats större än saldo (Nytt bet).
{
cout<<"Invalid bet, your balance is ("<<balance<<")"<<endl;
cin>>bet;
}

if (bet > 5000 || bet < 1 ) //Insats större än 5000 eller mindre än 1 (Nytt bet).
{
cout << "The amount you entered isn't valid, please try again"<<endl;
cin >> bet;
}

if (bet <= 5000 && deposit >= 1)
{
balance -= bet;
cout<<"Your bet is ("<<bet<<") and your balance is now ("<<balance<<')'<<endl;
}

}
}