Can anyone explain the interaction of switch, while and continue? - c

How is the switch statement executed here?
I am especially interested in the use of continue.
#include <stdio.h>
int main()
{
char ch = 'A';
while (ch <= 'D')
{
switch (ch)
{
case 'A':
case 'B':
ch++;
continue;
case 'C':
case 'D':
ch++;
}
printf("%c", ch);
}
}
This outputs DE, as you can see live on coliru.

Short answer: Continue corresponds to the while loop in the code.
Initially, value of ch is A and it matches the first case and since your cases don't have break, once a case is triggered, switch will go through all cases (until break, exit, continue, end of cases etc...). As a result it also enters case B and increments the ch to B. Since it encounters the continue it skips the rest of the instructions and begins the next iteration of the while loop.
You can run it in debugger to understand these things. You can also use the old-school printfs if needed.
There is also SO thread which discuss in detail about continue in switch

Here in char variable ' A' is 65 and 'D' is 68 .If the char value less then or equal in the condition the while loop will run. then in switch condition ch is the value which you defined earlier then the variable value match with the condition of case and increase the value of ch

Related

How to Compare char array with char in C language

What's wrong in the below code?
I am stuck in the do while loop. Am I comparing character wrong? I tried using scanf("%c", &answer); as well but same result
char answer[10];
for (i = 0; i < wish; i++)
{
/* ... */
/* ... */
do
{
printf(" Does this item have financing options? [y/n]:");
scanf("%s", &answer[i]);
if ((answer[i] != 'y' )|| (answer[i] != 'n'))
{
printf("\nERROR: Must be a lowercase 'y' or 'n'");
}
} while ((answer[i] != 'y') || (answer[i] != 'n'));
You are stuck in your loop because your condition for continuing the loop is always true.
If you have trouble seeing that try to name a letter which is neither different to "y" nor different to "n".
Take for example "a", it is different to both.
Take for example "n", it is not different to "n", but it IS different to "y".
Take for example "y", it is different to "n", though not different to "y".
So whatever letter comes in, the loop will continue.
To solve, use the comment by Chris and change to
((answer[i] != 'y' ) && (answer[i] != 'n'))
This way, any other letter than "n" or "y" will be either different than "n" AND different than "y" and will continue the loop, while both "y" and "n" will be different from at least one of the two and end the loop.
Once you got the condition right it might only be necessary once, i.e. only in the loop. The additional if is unneeded, at least in the shown code. You might have code which needs it, outside of what you show here.
Building on #Yunnosch's excellent answer, there us another way of looking at the logic of checking to see if something is not a set of characters.
We can look at it as checking to see if a character is not 'y' and not 'n':
answer[i] != 'y' && answer[i] != 'n'
Or... we can check to see if it is either 'y' or 'n':
answer[i] == 'y' || answer[i] == 'n'
Then simply negate that!
!(answer[i] == 'y' || answer[i] == 'n')
Another alternative
One more way of looking at this, because char is a numeric type, would be to use a switch.
switch (answer[i]) {
case 'y':
case 'n':
/* Do whatever happens when there is a valid input */
break;
default:
printf("\nERROR: Must be a lowercase 'y' or 'n'");
}
The only real advantage of using switch here is that it makes checking for things like capital y and n very easy:
switch (answer[i]) {
case 'y': case 'Y':
case 'n': case 'N':
/* Do whatever happens when there is a valid input */
break;
default:
printf("\nERROR: Must be a lowercase 'y' or 'n'");
}

What is the difference between the following two uses of `putchar`?

I was writing some code where I was getting an unexpected output in one part of the program, which in turn disrupted the entire system.
The code can be simplified and shortened to:
char ch;
printf("Enter Number: ");
while ((ch = getchar()) != '\n') {
if (ch >= 65 && ch <= 67) {
ch = 2;
}
putchar(ch);
}
As per the code above, I am trying to print a character/integer sequence of the user's choice. The numbers should remain unchanged whereas if the user enters letter A, then this should print 2.
Expected Output
Enter Number: 23-AB
23-22
Actual Output
Enter Number: 23-AB
23-☺☺
Once confronted with this problem, I decided to tweak some things and came up with the following code which worked perfectly. It uses the same approach but produces different output:
char input;
printf("\nEnter Number: ");
while ((ch = getchar()) != '\n') {
switch (toupper(ch)) { //toupper function not really needed since I am expecting the user to enter upper-case letters ONLY
case 'A': case 'B': case 'C':
printf("2");
break;
default:
putchar(ch);
}
}
Expected Output
Enter Number: 23-AB
23-22
Actual Output
Enter Number: 23-AB
23-22
I am unable to comprehend why I am failing to convert the ASCII value of the characters entered in the first code to a single integer. What is the reason for this difference in the outputs? I have simply changed the type of controlling expression, from if-statement to a switch-statement (or so I think). How can I alter the first code to provide me with the same output as the second code?
In the first version, setting ch=2; makes ch the character with ASCII value 2, not the character 2. ch=0x32; in your first version would probably work, since ASCII 50 = 0x32 is character 2. Even easier (and better, as Weather Vane points out) is ch='2';.
In your second version, you are using printf("2"). As a result, the compiler is producing the ASCII value for you when it processes the string "2", just as it would for ch='2';. Try printf("%d\n",'2'); and you should see 50.

what happens when there are two continuous breaks in a switch statement?

#include <stdio.h>
int main()
{
int i = 0;
char c = 'a';
while (i < 2){
i++;
switch (c) {
case 'a':
printf("%c ", c);
break;
break;
}
}
printf("after loop\n");
}
What will be the output of the above code?
Does the second break mean anything?
break is a jump statement in C. It unconditionally transfers control to a different location in the code. Which means that any code between that break and the target point of the jump is unreachable, unless there's a label that allows one to reach it.
In your case there's no such label. The second break is unreachable and has no effect.
There is no use for a second break statement.
The break statement has the following two usages:
When the break statement is encountered inside a loop, the loop is immediately terminated and program control resumes at the next statement following the loop.
It can be used to terminate a case in the switch statement.
In this case it terminates the case statement. So the second break doesn't get called. It is a useless statement.

C while loop - code won't work

I've been writing a simple program to check if input letter is a vowel, and my code doesn't work.
The program should take characters as input one by one until % is entered, which will make it exit. It checks if input chars are vowels, and prints the result. Also it reports an error if input is not a letter.
The problem is, it breaks out of the loop on the second step.
Thank you for help, in advance.
PS Sorry, didn't write that there's no error message, it just breaks out of the loop.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main(void)
{
char processed='q';
while(processed != '%')
{
printf("Enter letter to check if it's a vowel, %% to quit.\n");
char input = getchar();
processed = tolower(input);
printf("%c\n", processed);
if (processed == '%')
break;
if (processed < 'a' || processed > 'z')
{
fprintf(stderr, "Input should be a letter\n");
exit(1);
}
switch(processed)
{
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
case 'y':
printf ("Vowel\n");
break;
default:
printf ("Non-vowel\n");
}
}
exit(0);
}
Presumably you're entering a character and then hitting [ENTER]. So, in actuality you are entering two characters -- the letter you typed and a line feed (\n). The second time through the loop you get the line feed and find that it's not a letter, so you hit the error case. Perhaps you want to add something like:
if (processed == '\n') {
continue;
}
Someone else mentioned that you're hitting enter after each letter of input, and thus sending a newline ('\n') into your program. Since your program doesn't have a case to handle that, it isn't working right.
You could add code to handle the newline, but using scanf would be easier. Specifically, if you replaced
char indent = getchar();
with
char indent;
scanf("%c\n", &indent);
scanf() would handle the newline and just return back the letters you're interested in.
And you should check scanf()'s return value for errors, of course.

Menu that accepts single character in C language

I want to create a simple menu in C program that accepts single character. The menu will be like this:
[S]how
[E]xit
If the user enter '1','s' or 'S' the program will print "Hello" and prompt again for the input
else if the user enters '2',E or 'E' the program ends.
else it should print "invalid input" and prompt again.
I am able to create the program but the problem is that when user enters 12, 13, 14, 15, 16.....so on starting with 1, it shows Hello and same for other options.
My code is:
#include <stdio.h>
void clearBuffer();
int main() {
int i = 0;
char selection;
do
{
printf("\t1. [S]how\n");
printf("\t2. [E]xit\n");
printf("Enter your selection from the number or character noted above: ");
scanf("%s", &selection);
clearBuffer();
if (selection == '1' || selection == 's' || selection == 'S')
printf("Hello");
else if (selection == '2' || selection == 'E' || selection == 'x')
i = 0;
} while(i != 0);
}
void clearBuffer()
{
while(getchar() != '\n');
}
If you are going to receive only one character consider replacing the scanf() function for getchar() function:
printf("Enter your selection from the number or character noted above: ");
selection = getchar();
You could use strlen, which is part of the standard C library, to check the length of the string returned by scanf and reject entries longer than one character:
if (strlen(selection) > 1)
{
printf("Invalid selection.");
}
Alternatively, I think you could use getchar() to accept just a single character from the user, which means they wouldn't have to press enter.
As already mentioned, you should use getchar() if you only want one character. If you still want to use scanf() for whatever reason you may have, the correct format is "%c", not "%s".
I would also suggest that if you are looking for a single character, the if block looks a little "busy" (read, awkward) ... a switch would be a cleaner, more elegant way to do it (IMHO).
/* something like this ... */
switch ( selection ) {
case '1':
case 's':
case 'S':
printf ( "Hello\n" );
break;
case '2':
case 'e':
case 'E':
i = 0;
break;
}
Other couple of things ... if you don't care about the case of the character being read (that is, 's' and 'S' will do the same thing), you can convert selection to uppercase before your if-block or switch-block using toupper(). Also, and this is just a style suggestion, don't use i for your exit flag. General practice is to use things like i and j for counters or indexes - you could use something like quit_now or user_done which would convey more precisely what the variable means.

Resources