I've been writing a little C code, and I want switch to compare multiple characters in a string, but currently I can only get it to check one character.
What i would really like is for it to test if the input was yes, rather than just the first character of the input, so in this case, the y, or the n.
Here is my code:
switch (d[0]){
case 'y':
printf("Welcome ");
printf("%s\n", c);
break;
case 'n':
printf("Please Select A New User Name\n");
memset(&c[0], 0, sizeof(c));
goto name;
break;
case 'N' :
printf("Please select a new user name\n");
memset(&c[0], 0, sizeof(c));
goto name;
break;
case '\n':
printf("that is not a valid command, please try again\n");
memset(&d[0], 0, sizeof(d));
goto LOOP;
break;
case 'Y':
printf("Welcome ");
printf("%s\n", c);
break;
default :
printf("That is not a valid command, please try again\n");
goto LOOP;
break;
That's not what switch is for, it's for taking decisions based on an integer-valued expressions.
You need to use strcmp() to compare strings:
if(strcmp(d, "y") == 0)
{
printf("Welcome");
/* ... */
}
else if(strcmp(d, "n") == 0 || strcmp(d, "N") == 0)
{
printf("Please select a new user name\n");
/* ... */
}
Note that the above assumes that d is a properly-terminated string, i.e. not just a char.
ISO 9899 6.8.4.2
The controlling expression of a switch statement shall have integer type.
So passing string is not possible.
You simply can't.
Instead you have to resort to multiple if and else if statements comparing either individual characters or using strcmp to compare strings.
May be you can do it this way?
switch (d[0])
{
case 0x79:
printf("Welcome ");
printf("%s\n", c);
break;
case 0x6E:
printf("Please Select A New User Name\n");
memset(&c[0], 0, sizeof(c));
goto name;
break;
case 0x4E:
printf("Please select a New user name\n");
memset(&c[0], 0, sizeof(c));
goto name;
break;
case 0x0A:
printf("that is not a valid command, please try again\n");
memset(&d[0], 0, sizeof(d));
goto LOOP;
break;
case 0x59:
printf("Welcome ");
printf("%s\n", c);
break;
default :
printf("That is not a valid command, please try again\n");
goto LOOP;
break; // Does it really need a break here?????
}
Related
When the user inputs Yes,Only Maths,Only Science, the compiler executes Default.
I've tried with the same code but with Char replaced with Int it works as intended.. but with char it dosen't..
#include<stdio.h>
int main(){
char a;
printf("Have you passed in both maths and science?[Yes,Only Maths,Only Science]");
scanf(" %c", &a);
switch (a){
case 'Yes':
printf("That's amezing!");
break;
case 'Only Maths':
printf("That's good!");
break;
case 'Only Science':
printf("That's good!");
break;
case 'none':
printf("oof work harder next time!, i hope you will rock on that exam!");
break;
default:
printf("bozo do the typing right!");
break;
}
return 0;
}
A char by itself cannot store a string like "Yes". It will only store the first 'Y' and leave the rest. This is why none of the switch cases will match. Consider using string or char array to store an array of chars which can be compared. However, then the problem becomes that you cannot use switch with strings in C so you must use if, else.
#include <stdio.h>
int main(){
char a[15]; //15 should be a reasonable size
printf("Have you passed in both maths and science?[Yes,Only Maths,Only Science]");
fgets(a, 15, stdin);
if (strcmp(a, "Yes") == 0) printf("That's amezing!");
else if (strcmp(a, "Only Maths") == 0) printf("That's good!");
else if (strcmp(a, "Only Science") == 0) printf("That's good!");
else if (strcmp(a, "none") == 0) printf("oof work harder next time!, i hope you will rock on that exam!");
else printf("bozo do the typing right!");
return 0;
}
It is also recommended to use fgets instead of scanf to read strings.
I am trying to create a program, in which at the beginning it shows a menu to the user, which consists in a do{ ... }while; which reads an int., with a switch inside.
It works perfectly to read and check the integer, the problem is when writing a character or string, which gets stuck in an infinite loop showing the default message of the switch loop. The code is as follows:
int op;
printf("Choose an option:\n 1. option 1\n 2. option 2\n 3. option 3\n");
do{
scanf("%d", &op);
switch(op){
case 1: (instruction); break;
case 2: (instruction); break;
case 3: (instruction); break;
default: printf("\nPlease enter a valid option\n");
}
}while(op<1 || op>3);
It works perfectly to read and check the integer, the problem is when writing a character or string, which gets stuck in an infinite loop showing the default message of the switch loop.
scanf("%d", &op); does nothing when the input is not a valid int, you need to check the return value is 1 and if not to decide what to do like for instance read a string or flush up to the end of line, also managing the EOF case
Note in case scanf does nothing op is not set
So can be :
int op;
printf("Choose an option:\n 1. option 1\n 2. option 2\n 3. option 3\n");
do{
if (scanf("%d", &op) != 1) {
// flush all the line
while ((op = getchar()) != '\n') {
if (c == EOF) {
puts("EOF, abort");
exit(0); /* what you want */
}
}
op = -1; /* invalid value */
}
switch(op){
case 1: (instruction); break;
case 2: (instruction); break;
case 3: (instruction); break;
default: puts("\nPlease enter a valid option");
}
}
}while(op<1 || op>3);
I encourage you to never trust on an input and always check return value of scanfetc
The %d conversion specifier is seeking for decimal input only. It does not work to consume characters or strings. If you input a character instead of an decimal value, the directive will fail, and because op isn´t initialized you have undefined behavior.
To catch a string with scanf() use the %s conversion specifier or use fgets(). For only catching one character use the %c conversion specifier with scanf().
int DisplaySchedule()
{
int nDisplaySchedule_Choice;
system("cls");
printf("----- DISPLAY SCHEDULE -----\n");
printf("Pick departure station\n\t");
printf("[1] San Pedro\n\t");
printf("[2] Santa Rosa\n\t");
printf("[3] Calamba\n\n\t");
printf("[9] Go Back\n\t");
printf("[0] Exit\n\n");
printf("Choice: ");
scanf("%d", &nDisplaySchedule_Choice);
printf("\n");
switch (nDisplaySchedule_Choice) {
case 1: SanPedro(); break;
case 2: SantaRosa(); break;
case 3: Calamba(); break;
case 9: OpeningScreen(); break;
case 0: printf("Summary()"); break;
default:
printf("ERROR. INPUT A VALID RESPONSE.\n\n");
DisplaySchedule();
break;
}
return;
}
I have this code in which when I enter a letter, instead of printing the error message, it prints case 0: instead. Is there any way for me to make it so that case 0: will only function if and only if I enter "0" in the scanf statement?
You have undefined behaviour here.
scanf, when scanning for int (%d), fails because you input a character - due to matching failure. Thus not reading anything into nDisplaySchedule_Choice at all.
Since nDisplaySchedule_Choice is uninitialized to start with, it just happens to have 0 and thus goes to case 0.
The solution is to check the scanf return value before proceeding to use nDisplaySchedule_Choice. scanf returns the number of items successfully scanned.
If scanf fails to read a value (for instance because you told it to read an int and gave it a letter) it won't change your variable. So nDisplaySchedule_Choice won't change in a way that you can check in your switch. At least not if you don't initialize it - you can however set it to a value that is not covered by your switch, and if it didn't change, you know that scanf failed to read a value.
Or you could check the return value of scanf to see if it managed to read a value:
int result = scanf("%d", &nDisplaySchedule_Choice);
if (result == 0) {
int c;
while ((c = getchar()) != '\n' && c != EOF); // flush the invalid input
printf("ERROR. INPUT A VALID RESPONSE.\n\n");
DisplaySchedule();
}
else switch ...
Hi please take a look on this code:
while (cont == 1) {
...
scanf_s("%d", &input);
if (0 < input <= 5){
switch (input) {
case 1:
printf("1");
break;
case 2:
printf("2");
break;
case 3:
printf("3");
break;
case 4:
printf("4");
break;
case 5:
cont = 0;
break;
default:
printf("Wrong input !");
break;
}
}else{
printf("Error, Not a number !");
}
}
If I input something that is not a number, it results in an infinite loop. How do I restrict char inputs?
You can use this:
if(scanf_s("%d", &input) != 1) {
printf("Wrong input !");
break;
}
You should ALWAYS check the return value of scanf_s anyway.
After the scanf_s() fails, you need to read at least one character (the character that it failed on); usually, it makes most sense to discard the rest of the line that the user entered:
while (cont == 1) {
int rc;
...
if ((rc = scanf_s("%d", &input)) < 0)
{
printf("EOF detected\n");
break;
}
if (rc == 0)
{
int c;
while ((c = getchar()) != EOF && c != '\n')
;
printf("Error, Not a number!\n");
continue;
}
if (0 < input <= 5){
switch (input) {
case 1:
case 2:
case 3:
case 4:
printf("%d", input);
break;
case 5:
cont = 0;
break;
default:
printf("Wrong input (1-5 required)!\n");
break;
}
}
}
If EOF is detected in the 'gobble' loop, you could detect EOF there and repeat the print and break the loop immediately. OTOH, the next scanf_s() should also report EOF, so it isn't 100% necessary. It depends a little on where the prompting occurs; if you get EOF, you probably shouldn't prompt again, so maybe the test after the inner while loop should be:
if (c == EOF)
{
printf("EOF detected\n");
break;
}
else
{
printf("Error, not a number\n");
continue;
}
You can play with variants of the 'gobble' loop that read up to a newline or a digit, and use ungetch(c, stdin); to return the digit to the input stream for the next call to scanf_s() to process — you probably wouldn't prompt for more input if you're going to process the already entered digit (that would confuse).
There are endless other games you can play. One option to consider is limiting the number of failed inputs before you give up — if the user hasn't entered a valid number in 10 tries, they probably aren't going to.
Note how the error processing tells the user what the valid range of numbers is; that helps them get it right. Also notice that the messages have a newline at the end; that's generally a good idea. In contexts outside interactive I/O, the newline can help ensure that the output appears when it is printed, not some arbitrary time later when some other print adds a newline, or the output buffer fills up and the pending data is flushed after all.
I am trying to make a simple option menu that is executed within a do- while loop. The menu has 5 different options. I am currently trying to test the the get initial option but when I choose the case 'b' the function does not even execute and the option menu reappears again
#include "mathprogram.h"
int main (void)
{
char menu_option,initials;
int difficulty;
printf(" EDUCATIONAL MATH PROGRAM!!!\n");
printf("------------------------------------------\n\n");
do{
printf("Main Menu\n");
printf("a. Learn about how to use program.\n");
printf("b. Enter your initials (3 individual letters).\n");
printf("c. Difficulty Selection.\n");
printf("d. Start a new sequence of problems.\n");
printf("e. Save and quit.\n");
printf(" Please enter an option from the main menu: ");
scanf("%c",&menu_option);
switch(menu_option){
case 'a':
//Learn_to_use();
break;
case 'b':
initials=get_intials();
break;
case'c':
printf("case c");
//difficulty = get_difficulty();
break;
case'd':
break;
case'e':
break;
default:
printf("invalid input");
break;
}
}while(menu_option !='e');
}
get initials function:
#include "mathprogram.h"
char get_intials(void){
char initails;
printf("Please Enter Initials: ");
scanf("%c",&initails);
return initails;
}
scanf("%c", &var);
leaves the newline in the buffer or stream.
Try to change it to
scanf(" %c", &var);
and it should work as expected (Note the space before the %; this consumes the whitespace so that the next scanf call should work).
However, the initials as defined in your program consist of only one character, not three. I'll leave that up to you to design, that is a different question.
There's a '\n' between option 'b' and the initials char, the "scanf" must handle it.
Complete code that works:
#include <stdio.h>
char get_intials(void){
char initails;
printf("Please Enter Initials: ");
scanf("\n%c",&initails) ;
return initails;
}
int main (void)
{
char menu_option,initials;
int difficulty;
printf(" EDUCATIONAL MATH PROGRAM!!!\n");
printf("------------------------------------------\n\n");
do{
printf("Main Menu\n");
printf("a. Learn about how to use program.\n");
printf("b. Enter your initials (3 individual letters).\n");
printf("c. Difficulty Selection.\n");
printf("d. Start a new sequence of problems.\n");
printf("e. Save and quit.\n");
printf(" Please enter an option from the main menu: ");
scanf("%c",&menu_option);
switch(menu_option){
case 'a':
//Learn_to_use();
break;
case 'b':
initials=get_intials();
printf( "input initials:%c\n", initials) ;
break;
case'c':
printf("case c");
//difficulty = get_difficulty();
break;
case'd':
break;
case'e':
break;
default:
printf("invalid input");
break;
}
}while(menu_option !='e');
}
output:
Please enter an option from the main menu: b
Please Enter Initials: c
input initials:c
/*
This code includes a stray \n from previous input due to which get_initials method was not working properly,it picked up the remanant \n in the input stream and concluded,
flushing the input stream is the solution to the problem, uncomment the code at line 8 to get proper functionality
*/
#include <stdio.h>
char get_intials(void){
char initails;
//fflush(stdin);
printf("Please Enter Initials: ");
scanf("%c",&initails);
return initails;
}
int main (void)
{
char menu_option,initials;
int difficulty;
printf(" EDUCATIONAL MATH PROGRAM!!!\n");
printf("------------------------------------------\n\n");
do{
printf("Main Menu\n");
printf("a. Learn about how to use program.\n");
printf("b. Enter your initials (3 individual letters).\n");
printf("c. Difficulty Selection.\n");
printf("d. Start a new sequence of problems.\n");
printf("e. Save and quit.\n");
printf(" Please enter an option from the main menu: ");
fflush(stdin);
scanf("%c",&menu_option);
switch(menu_option){
case 'a':
//Learn_to_use();
break;
case 'b':
initials=get_intials();
if(initials == '\n')
printf("\n%s\n","I was there in stream as newline");
//printf("\n%c",initials);
break;
case'c':
printf("case c");
//difficulty = get_difficulty();
break;
case'd':
break;
case'e':
break;
default:
printf("invalid input");
break;
}
}while(menu_option !='e');
return 0;
}