default is not working on my switch (c++) - c++

My problem it's very simple to explain, but I have no idea to solve it.
In my switch statement in the code that you can see below, the default case does not work, but if I remove the last return ""; works fine.
Like something so simple can lead a person to the path of bitterness?
Greetings and thank you very much in advance
QString sim900::loop() {
QString text = readSerial();
if (text != "")
{
QStringList commands;
// 0 1 2 3 4 5
commands << "+RECEIVE" << " CLOSED" << "REMOTE IP: " << "+CMTI: " << "+CSQ: " << "+CIPSEND=";
for (int n=0; n<commands.length(); n++)
{
if (text.indexOf(commands[n]) != -1)
switch (n)
{
case 0:
SocketReceive(text, false);
break;
case 1:
DropClient(text);
break;
case 2:
NewClient(text);
break;
case 3:
break;
case 4:
EstadoRed(text);
break;
case 5:
ReadyToSend(text);
break;
default:
if (n == commands.length()-1)
return text;
}
}
}
return "";
}

Consider this...
for(int n = 1; n < 2; ++n) {
switch (n) {
case 0:
break;
default:
std::cout << "Whoops!";
}
}
this will print "Whoops!" once. That's because I start outside the cases which I handle - a default case.
Now, consider this...
int commandsLength = 6;
for(int n = 0; n < commandsLength; ++n) {
switch (n) {
case 0:
break;
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
default:
if (n == commandsLength - 1)
std::cout << "Whoops!";
}
}
and the fact the default case can never be reached because I handle the 5 case and due to the condition on the for n cannot be >= 6. This is the situation you've created for yourself.

Related

Why do I keep getting this error: exception Unhandled : Unhandled exception thrown: read access violation. this was 0x4

I am currently working on the BlackJack project, but there is an error showing "exception Unhandled: Unhandled exception thrown: read access violation. this was 0x4.". I am not quite sure which part I did wrong, and the program sometimes runs normally sometimes shows that exception. In draw_card function, it returns a value of a random number. For example: if we get 13, the value will be 10. It also returns the name of the card and the type of the card such as 13 corresponds to king.
int main()
{
srand(time(0));
unsigned bet;
int player = 0 , dealer = 0;
string card , type;
cout << "You have $100. Enter bet: ";
cin >> bet;
cout << "Your cards are:" << endl;
player += draw_card(card, type, player);
cout << " "+card + " of " + type << endl;
player += draw_card(card, type, player);
cout << " " + card + " of " + type << endl << endl << endl;
}
int draw_card(string& card, string& type, int drawer_points) {
int randomNumber; //between 1 and 13
int suite; //between 1 and 4 to determine the suite of the card.
randomNumber = rand() % 13 + 1;
suite = rand() % 4 + 1;
card = getRank(randomNumber);
type = getSuit(suite);
if (randomNumber == 13 || randomNumber == 12 || randomNumber == 11) {
return 10;
}else if (randomNumber == 1) {
int ace1 = 21 - (drawer_points + 1);
int ace2 = 21 - (drawer_points + 11);
return ace1 < ace2 ? 1 : 11;
}
else
{
return randomNumber;
}
}
string getSuit(int suit) {
switch (suit)
{
case 0:
return "spades";
break;
case 1:
return "clubs";
break;
case 2:
return "diamonds";
break;
case 3:
return "hearts";
break;
default:
break;
}
}
string getRank(int rank) {
switch (rank)
{
case 13:
return "King";
break;
case 12:
return "Queen";
break;
case 11:
return "Jack";
break;
case 1:
return "Ace";
break;
case 2:
return "Two";
break;
case 3:
return "Three";
break;
case 4:
return "Four";
break;
case 5:
return "Five";
break;
case 6:
return "Six";
break;
case 7:
return "Seven";
break;
case 8:
return "Eight";
break;
case 9:
return "Nine";
break;
case 10:
return "Ten";
break;
default:
break;
}
You generate
suite = rand() % 4 + 1;
This is a random number between 1 and 4 inclusive.
You then call
getSuit(suite);
But getSuit only has switch branches for values between 0 and 3 inclusive:
switch (suit)
{
case 0:
return "spades";
break;
case 1:
return "clubs";
break;
case 2:
return "diamonds";
break;
case 3:
return "hearts";
break;
default:
break;
}
Not returning a value from a function that is declared to return a value is undefined behaviour.
A few functions like getSuit and getRank in your code don't return a value if only the default case of their switch statement is executed.
You can return an empty string in the default cases:
default:
return ""; // empty string
And in the call site, check to see if the returned value is empty using the empty function.
Another way is to use std::optional<T> like below:
std::optional<string> getSuit( const int suit )
{
switch (suit)
{
case 0:
return "spades";
case 1:
return "clubs";
case 2:
return "diamonds";
case 3:
return "hearts";
default:
return { }; // empty optional
}
}
And in the call site:
std::optinal<std::string> type { getSuit(suite) };
if ( type ) // if optional has value
{
// extract and use the value inside of optional
type.value( );
}
Keep in mind that if the optional does not have a value, using value() will throw. You can use value_or() instead which does not throw.

C++ pull a card from deck

I'm trying to create a program that will pull a card from a deck of 52 regular playing cards.
Suits: Heart, Spad, Diamond, Club.
Rank: A,2,3,4,5,6,7,8,9,10,J,Q,K.
This should be the output:
Let's pull a card!
This time we got AH
Wanna pull a card again?
y
This time we got 3J
Wanna pull a card again?
n
My output is:
Let's pull a card!
DKThis time we got 00
Wanna pull a card again?
n
This is my code:
#include <iostream>
#include <ctime>
using namespace std;
// Function Declaration
int rankCard(), suitCard();
int main()
{
srand(time(0));
char answer;
cout << "Let's pull a card!" << endl;
do {
cout << "This time we got " << rankCard() << suitCard() << endl;
cout << "Wanna pull a card again?" << endl;
cin >> answer;
} while ((answer == 'y') || (answer == 'Y'));
return 0;
}
int rankCard() {
int rank = (rand() % 13) + 1;
switch (rank) {
case 1: cout << "A";
break;
case 10: cout << "T";
break;
case 11: cout << "J";
break;
case 12: cout << "Q";
break;
case 13: cout << "K";
break;
default: cout << rank;
break;
}
return 0;
}
int suitCard() {
int suit = (rand() % 4) + 1;
switch (suit) {
case 1: cout << "H";
break;
case 2: cout << "D";
break;
case 3: cout << "C";
break;
case 4: cout << "S";
break;
}
return 0;
}
I can't figure out why the cards pulled (DK) are in that position and why I also get the 00. What am I doing wrong? Thanks
Your calls to rankCard() and suitCard() always return 0.
That 0 value is what's passed to cout in your main function.
The weird 'DK' is caused by the calls to cout inside rankCard and suitCard.
You could modify your functions to avoid the confusion:
#include <string>
std::string rankCard() {
int rank = (rand() % 13) + 1;
switch (rank) {
case 1: return "A";
case 10: return "T";
case 11: return "J";
case 12: return "Q";
case 13: return "K";
default: return std::to_string( rank );
}
return "";
}
std::string suitCard() {
int suit = (rand() % 4) + 1;
switch (suit) {
case 1: return "H";
case 2: return "D";
case 3: return "C";
case 4: return "S";
}
return "";
}
This line:
cout << "This time we got " << rankCard() << suitCard() << endl;
So those functions print the card, and then they return 0, so if you call them in cout, they will do their thing witch is printing the card and then print the return value witch is 0.
What you can do is to call them outside the cout, just do:
//...
cout << "This time we got ";
rankCard();
suitCard();
cout << endl;
cout << "Wanna pull a card again?" << endl;
//...
Personally I would refactor the functions to return the respective card char:
Live sample
const char rankCard() {
int rank = (rand() % 13) + 1;
switch (rank) {
case 1: return 'A';
case 10: return 'T';
case 11: return 'J';
case 12: return 'Q';
case 13: return 'K';
default: return rank + 48; // convert to decimal digit
}
}
const char suitCard() {
int suit = (rand() % 4) + 1;
switch (suit) {
case 1: return 'H';
case 2: return 'D';
case 3: return 'C';
case 4: return 'S';
default: return 0; //ASCII code for null character
}
}

C++ program to convert string to numeric digits

I'm trying to create a function that converts input words to numeric digits like a mobile numpad. It is for an assignment. I cannot use cstring or character arrays.
Can someone please identify and correct the error in my code? It currently gives the error: ISO C++ forbids comparison between pointer and integer [-fpermissive].
I am not using any pointer variables. I do have used the strlen() function to determine the exact place of a character in a string. Any help is greatly appreciated.
#include<iostream>
#include<conio.h>
#include<string.h>
#include<stdio.h>
using namespace std;
void Letter_correspondence();
int main()
{
Letter_correspondence();
return 0;
}
void Letter_correspondence()
{
cout<<"Enter the letters of the word you want to convert to numbers: ";
char a[]="Hello";
char b[]="world";
int len=strlen(a);
int lenb=strlen(b);
int n;
int l=a[n];
for (n=0;n<=7;n++)
{
while (n<=len)
{
if (l=="a"||l=="b"||l=="c")
{
if (n==2)
{
cout<<"-";
}
cout<<"2";
}
else if (l=="d"||l=="e"||l=="f")
{
if (n==2)
{
cout<<"-";
}
cout<<"3";
}
else if (l=="g"||l=="h"||l=="i")
{
if (n==2)
{
cout<<"-";
}
cout<<"4";
}
else if (l=="j"||l=="k"||l=="l")
{
if (n==2)
{
cout<<"-";
}
cout<<"5";
}
else if (l=="m"||l=="n"||l=="o")
{
if (n==2)
{
cout<<"-";
}
cout<<"6";
}
else if (l=="p"||l=="q"||l=="r"||l=="s")
{
if (n==2)
{
cout<<"-";
}
cout<<"7";
}
else if (l=="t"||l=="u"||l=="v")
{
if (n==2)
{
cout<<"-";
}
cout<<"8";
}
else if (l=="w"||l=="x"||l=="y"||l=="z")
{
if (n==2)
{
cout<<"-";
}
cout<<"9";
}
}
}
}
If I understood this right, you're trying to map characters to different ones and print them. You said you cannot use cstring or character arrays, but you do that here:
char a[]="Hello";
char b[]="world";
Instead, I would just use std::string:
std::string a = "Hello";
You can then iterate through it using a range-based for loop. The best way to print your string would probably be using a switchstatement:
for (char &c : a)
{
switch (tolower(c)) {
case 'a':
case 'b':
case 'c':
std::cout << 2;
break;
case 'd':
case 'e':
case 'f':
std::cout << 3;
break;
case 'g':
case 'h':
case 'i':
std::cout << 4;
break;
case 'j':
case 'k':
case 'l':
std::cout << 5;
break;
case 'm':
case 'n':
case 'o':
std::cout << 6;
break;
case 'p':
case 'q':
case 'r':
case 's':
std::cout << 7;
break;
case 't':
case 'u':
case 'v':
std::cout << 8;
break;
case 'w':
case 'x':
case 'y':
case 'z':
std::cout << 9;
break;
default:
std::cout << c;
}
}
If you're using an old version of C++ that doesn't support range based for loops, change this
for (char &c : a)
{
switch (tolower(c)) {
To this
for (size_t i = 0; i < a.size(); i++)
{
switch (tolower(a[i])) {
And std::cout << c; to std::cout << a[i];.

If statements in for loops

how do I run only one of those if statements in a for loop? For example i have an input of 5...and i just want it to print five...but whenever i run this code, it will execute all if statement..please help me
#include <iostream>
#include <cstdio>
using namespace std;
int main() {
// Complete the code.
int a;
int b;
cin >> a;
for (a = 0; 0<a<10; a++)
{
if (a == 1)
{
cout << "one";
}
if (a == 2)
{
cout << "two";
}
if (a == 3)
{
cout << "three";
}
if (a == 4)
{
cout << "four";
}
if (a == 5)
{
cout << "five";
}
if (a == 6)
{
cout << "six";
}
if (a == 7)
{
cout << "seven";
}
if (a == 8)
{
cout << "eight";
}
if (a == 9)
{
cout << "nine";
}
else if (a > 9 && a%2 == 0)
{
cout << "even";
}
else if (a > 9 && a&2 != 0)
{
cout << "odd";
}
}
return 0;
}
The problem seems to be the for loop. Your program accepts a value for a as an input, but then as soon as the loop begins, it resets the value of a to 0 (for (a = 0;...
Therefore it's looping 10 times, and on each loop a will have a different value, starting from 0 and ending at 9. This means that all of your if statements will get hit at some point in the execution, generally one on each of the loops round the for.
To get your expected behaviour " input of 5...and i just want it to print five", simply remove the for loop from your code.
Your unnecessary for loop trashes the input value of a and loops forever! (At least until you overflow your signed type a).
You are replacing a by using it as the counter in the for loop! If you only ever want one output, then drop the for loop completely. If your for loop were to remain then your expression 0 < a < 10 ought to be recast as 0 < a && a < 10 : formally 0 < a < 10 is evaluated as (0 < a) < 10 which is either true < 10 or false < 10 which is always true.
Also consider refactoring your if else to set up explicitly mutually exclusive statements:
if (a == 1){
cout << "one";
} else if (a == 2){
cout << "two";
/*and so on*/
} else {
/*all other cases*/
}
Although in this case you might want to consider a switch block:
switch (a){
case 1:
cout << "one";
break; // to stop program control flowing into the next case
case 2:
cout << "two";
break;
/*and so on*/
default:
/*all other cases*/
}
if () {
} else if () {
}
Although,
switch() {
}
will be more efficient in your case.
Update 1
#Aleph0
Below is the solution
int main() {
int a;
cin >> a;
switch (a) {
case 1: cout << "one"; break;
case 2: cout << "two"; break;
case 3: cout << "three"; break;
case 4: cout << "four"; break;
case 5: cout << "five"; break;
case 6: cout << "six"; break;
case 7: cout << "seven"; break;
case 8: cout << "eight"; break;
case 9: cout << "nine"; break;
default: cout << ((a & (1 << 31)) ? "negative" : (a & 1) ? "odd" : "even"); break;
}
}
Question has been asked to do following
i have an input of 5...and i just want it to print five
And, someone has correctly mentioned above, for loop is immaterial here.

Getting a program to start over and get a new value?

I am working with a program which requires a value to put in a variable and do some stuff on it. The problem is that I want the program to start over again and ask the user for a new value to process the new value again.
For example look at this code, which requires a number as a grade to rate it. When the processing was done I want the program to ask for a new grade ( next student for instance ).
#include <iostream.h>
int main (int argc, const char * argv[])
{
int n;
cout<< " Please Enter your grade : " ;
cin>>n;
switch (n/10) {
case 10: cout<< " A+ : Great! ";
case 9:
break;
case 8: cout<< " A : Very Good ";
break;
case 7: cout<< " B : Good " ;
break;
case 6:
case 5:
case 4:
case 3:
case 2:
case 1:
case 0: cout<< " Failed ";
break;
default:
break;
}
return 0;
}
What you need is a while loop
int main (int argc, const char * argv[])
{
int n;
while(1) {
cout<< " Please Enter your grade : " ;
cin>>n;
switch (n/10) {
case 10: cout<< " A+ : Great! ";
case 9:
case 8: cout<< " A : Very Good ";
break;
case 7: cout<< " B : Good " ;
break;
case 6:
case 5:
case 4:
case 3:
case 2:
case 1:
case 0: cout<< " Failed ";
break;
default:
break;
}
cout<<"do you wish to continue?(y/n)";
cin>>some_declared_variable;
if (some_declared_variable == 'n')
break; //hopefully this will break the infinite loop
}
return 0;
}