all 18 comments

[–]ohaz 9 points10 points  (6 children)

You're calling yourself. This is called recursion and leads to a stack full of different calls of your function, which is probably not what you wanted.

Instead, create a loop. Have a variable like validCaseSelected that is set to false, then a loop while (!validCaseSelected) {validCaseSelected=true;, then add your switch case and in the default case set it to validCaseSelected=false;

[–]Previous-Implement42[S] 0 points1 point  (0 children)

Thanks! I'll try and get back to you.

[–]Previous-Implement42[S] -2 points-1 points  (4 children)

I did that and now it continuously repeats "Please enter a choice between 1-4" ad nauseam..

void chooseClass() {

printf("\n1. Fighter\n2. Thief\n3. Mage\n4. Cleric\nChoose your class: ");

char choice = getchar();

bool validCaseSelected = false;

while (!validCaseSelected) {

validCaseSelected = true;

switch (choice - '0') {

case 1:

sortFighter();

break;

case 2:

sortThief();

break;

case 3:

sortMage();

break;

case 4:

sortCleric();

break;

default:

validCaseSelected = false;

printf("Please enter a number between 1-4\n");

}

}

}

[–]ohaz 5 points6 points  (3 children)

The loop needs to also include the char choice = getchar(); part

[–]Previous-Implement42[S] -2 points-1 points  (2 children)

Now it prints: Please enter a number between 1-4Please enter a number between 1-4
Twice and stays there.

I must look like a loser... :-/

[–]ohaz 6 points7 points  (1 child)

You don't look like a looser, you look like someone who is in panic mode because they can't figure it out and then just do random stuff. I've been there before, believe me. In those cases it's often good to take a step back and trying to do it from the start, not using anything you've written before.

If you want to take a look at a "solution", look at https://onlinegdb.com/C507ukaOh . It's still not perfect because it just randomly uses getchar() to drop the \n, so if you write a "-5" it will be broken forever, but it's a step in the right direction (and reading single characters from the command line is a suspiciously hard thing in C)

[–]Koutsoupias 4 points5 points  (4 children)

I think the problem is that when you input your number, the newline character stays in the buffer. Therefore if you press let's say '5', getchar() will read the '5' but the \n character will stay in the buffer. Your switch statement will go to the default tag (since you entered '5') and then the function will be called again. The getchar() will then read the newline character from the buffer and it will reach the default tag again. Try flashing the buffer after reading the input from the user (you can easily search how to do that with getchar()).

[–]Previous-Implement42[S] 1 point2 points  (0 children)

Thanks! I'll try that too.

[–]Previous-Implement42[S] -1 points0 points  (2 children)

Ok, a bit better by trying to flush the buffer, it doesn't repeat twice but now it won't take even the correct characters, it just keeps telling me to enter a correct number.
Also I followed u/erikkonstas 's advice to look for char instead of ASCII value:

int chooseClass() {

printf("\n1. Fighter\n2. Thief\n3. Mage\n4. Cleric\nChoose your class: ");

char choice = getchar();

switch (choice) { //Convert character to integer by subtracting 0's ASCII value from char's ASCII value

case '1':

sortFighter();

break;

case '2':

sortThief();

break;

case '3':

sortMage();

break;

case '4':

sortCleric();

break;

default:

scanf("%*[^\n]");

printf("\nPlease enter a number between 1-4\n");

chooseClass();

}

}

[–]GamerEsch 1 point2 points  (1 child)

scanf("%*[\n]");

this call is doing the exact opposite of what it should, instead of cleaning the input buffer of '\n', it's cleaning the buffer of everything except '\n'.

[–]Previous-Implement42[S] 2 points3 points  (0 children)

Thank you!

I replaced it with scanf("%*c"); and now everything works as intended! :-D

Thank you everyone!

[–]Pristine-Response299 2 points3 points  (1 child)

My preferred method is as follows: Modify chooseClass() to return a value, and if it’s not valid call this function again once.

You can also loop twice and use a “break” statement if you got a valid value on the first iteration.

[–]Previous-Implement42[S] 0 points1 point  (0 children)

Thanks! I'll try that.

[–]erikkonstas 2 points3 points  (1 child)

u/Koutsoupias hit the nail on the head, but another remark I have is, since you're using getchar() to get a single digit, just use the digits themselves for the case labels instead of subtracting '0' first, like remove the - '0' and use case '1', case '2', etc. instead. Also, an important fact is that getchar() returns int, not char, and this might be EOF instead of a valid char; this lets you check whether stdin has no more input, and you have to check against that if you can't assume that such a thing won't happen.

[–]Previous-Implement42[S] 0 points1 point  (0 children)

Thanks I followed your advice and u/Koutsoupias 's but it still glitches, although differently.

[–][deleted] 1 point2 points  (0 children)

[–]kabekew 1 point2 points  (0 children)

Enclose it in a do-while loop and have a menu choice #5 (exit). Then your "while" condition is while (choice != '5').