nested switch case not working [closed] - c

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I am trying to execute some commands using USART communication and reading some values using ATmega32-A. have a look at my code . My problem is i am trying to add some cases (nested switch case) but i am not getting what i want. I hope i am giving all most all information required to solve my problem.
void uniCom(void) {
switch (Command) {
/* ... */
case (muxsel):
printf(muxselection);
switch (c) {
case 1:
printf("this is mux chaneel1");
DDRB = 0b10111111;
PORTB = 0b00000000;
printf("adc Value", ReadAdc());
Command = 0;
break;
case 2:
/*-------------------*/
break;
}
Command = 0;
break;
/* ... */
default:
Command = 0;
break;
}
}
The problem is undefined c. And I don't see any declaration of muxselection, maybe missing "" ? Now the second approach.
void selcase(void) {
unsigned char c;
printf("muxselection");
while (rx_counter0) {
c = getchar();
switch (c) {
case 1:
printf("this is mux chaneel1");
DDRB = 0b10111111;
PORTB = 0b00000000;
printf("adc Value", ReadAdc());
Command = 0;
break;
case 2:
/*-------------------*/
break;
}
}
}
void uniCom(void) {
switch (Command) {
/* ... */
case (muxsel):
printf(muxselection);
selcase();
Command = 0;
break;
/* ... */
default:
Command = 0;
break;
}
}
My problem is i am executing all the commands as i declared but i want to select some more cases in one of the main switch case command "muxsel". for that i wrote nested switch case. if i select "muxsel" command on hyperteminal then it is printing like "muxselection" then if i enter 1 to select "case '1'"in second switch, nothing is printing. it is printing "command not found". what is the problem. I want execute nested switch but i am not able to do that using above code I have tried like this also.
void selcase(void) {
unsigned char c;
printf("muxselection");
while (rx_counter0) {
c = getchar();
switch (c) {
case '1':
printf("this is mux chaneel1");
DDRB = 0b10111111;
PORTB = 0b00000000;
printf("adc Value", ReadAdc());
c= 0;
break;
case '2':
/*-------------------*/
break;
default;
break;
}
}
}
creating one function for nested switch case and calling in main switch case as shown below.
void uniCom(void) {
switch (Command) {
/* ... */
case (muxsel):
printf(muxselection);
selcase();
Command = 0;
break;
/* ... */
default:
Command = 0;
break;
}
}
this way also not working please suggest me how to overcome this problem. i want to select one of the command in main switch case such as "muxsel" after that i have select mux channels using case statement. any help appreciated.
Thanks in advance.
I have solved this problem.

OK... the code isn't terribly clear, but I think I see your problem.
You tried to modify the code like this:
case (muxsel):
printf(muxselection);
switch (c) {
case 1:
printf("this is mux chaneel1");
DDRB = 0b10111111;
PORTB = 0b00000000;
printf("adc Value", ReadAdc());
Command = 0;
break;
case 2:
First, you don't have c declared in the scope of the uniCom() function. So that would not compile. Because you didn't give full code I assume you know that and probably really did something like this:
void uniCom(void) {
unsigned char c;
c = getchar();
switch (Command) {
case (no_com):
Command = 0;
....
case (muxsel):
printf("muxselection\n"); //Need quotes here and maybe a \n?
switch (c) {
case 1:
...
Which leads to the next problem. You're asking for a char c but your cases are built on an int. For example, if the user enters 3, what you're getting is the character '3' or the int 51. Check the ASCII Table
So your cases are for start of header (SOH), start of text (STX), etc right now... that's not going to work the way you wanted it to. You need to either do this:
switch (c) {
case 51: // This is ASCII '1'
...
break;
case 52: // This is ASCII '2'
Or do this:
switch (c) {
case '1':
...
break;
case '2':
Since you didn't give your input, or how c was defined, I could be wrong... but I'm going to wager that's your problem. By the way, make sure you have a default case at the end with a message like "bad input", it makes this type of thing easier to catch.
EDIT:
Modify the code as follows and share the result:
void runCom(void){
unsigned char c;
c = getchar();
printf("%c %d\n", c, c); //<-- add this line here
switch(Command){
and
void selcase(void) {
unsigned char c;
printf("muxselection");
while (rx_counter0) {
c = getchar();
printf("%c %d\n", c, c); //<-- and this line here
switch (c) {

I wrote it as an answer 'cause there is no place for it in comments. Although it's definitely not a final satisfactory once, it might help you get there.
For now I see two problems. You say you tried altering case(muxsel). Your code cannot even compile in my opinion. The code for the function should look similar to this:
void uniCom(void) {
switch (Command) {
/* ... */
case (muxsel):
printf(muxselection);
switch (c) {
case 1:
printf("this is mux chaneel1");
DDRB = 0b10111111;
PORTB = 0b00000000;
printf("adc Value", ReadAdc());
Command = 0;
break;
case 2:
/*-------------------*/
break;
}
Command = 0;
break;
/* ... */
default:
Command = 0;
break;
}
}
The problem is undefined c. And I don't see any declaration of muxselection, maybe missing "" ?
Now the second approach.
void selcase(void) {
unsigned char c;
printf("muxselection");
while (rx_counter0) {
c = getchar();
switch (c) {
case 1:
printf("this is mux chaneel1");
DDRB = 0b10111111;
PORTB = 0b00000000;
printf("adc Value", ReadAdc());
Command = 0;
break;
case 2:
/*-------------------*/
break;
}
}
}
void uniCom(void) {
switch (Command) {
/* ... */
case (muxsel):
printf(muxselection);
selcase();
Command = 0;
break;
/* ... */
default:
Command = 0;
break;
}
}
The second case could compile probably. The thing I do not understand is, why in the 2nd case you do manually read c. While in the former you do not ? Should it be loaded within uniCom routine or not ? It sure is in getCom(). Maybe you should not mess with buffers from the level of uniCom or below. Also are you sure that while(rxcounter0) will ever stop ? And if getchar() means to read a character from standard input from a human user typing on a keyboard it might be hard to read 1 or 2 from him as these are pretty low ASCII codes not present there.

Related

stm32F4 7-segment display

I have a problem with programming quad 7-segment display. I don't know how to make all multiplexed chars blinking.
I'm programming in CooCox
multiplexing code (interrupt):
void TIM2_IRQHandler(){
if (TIM_GetITStatus(TIM2,TIM_IT_Update)) {
TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
GPIO_ResetBits(GPIOC,15); //turn off all display cells
switch (disp) {
case 1:
decodeCharacters(digits[(alarm.RTC_AlarmTime.RTC_Minutes-time.RTC_Minutes)%10]); //called method decoding chars
break;
case 2:
decodeCharacters(digits[(alarm.RTC_AlarmTime.RTC_Seconds-time.RTC_Seconds)/10]);
break;
case 3:
decodeCharacters(digits[(alarm.RTC_AlarmTime.RTC_Seconds-time.RTC_Seconds)%10]);
break;
default:
decodeCharacters(digits[(alarm.RTC_AlarmTime.RTC_Minutes-time.RTC_Minutes)/10]);
break;
}
GPIO_ToggleBits(GPIOC,1<<disp); //turn on display cell
disp = (disp+1)%4;
}
}
where "disp" is unsigned integer.
I understand that you have a code that displays time and you want to make your digits blinking.
First thing that you need to do is to check how often your interrupt handler occurs. Then inside this handler you can create a static variable which will count time, e.g.
static unsigned int blinkCounter = 0;
if( blinkCounter < 500 )
{
/* Turn off the display */
}
else
{
/* Most of your current handler code */
}
if( blinkCounter > 1000 )
{
blinkCounter = 0;
}
blinkCounter++;

C - Case statement failing to compare variable

I'm a little confused with the case statement in the PrintGenre function; it passes the value correctly, but defaults to Undefined.
Little bit of background; this is ultimately becoming a (very simple) text music player, and I think I've found an easier way to do this, but just for my overall understanding I wanted to figure out why this case statement isn't functioning the way I wanted it to.
If I remove the default option, it goes to the last case option in the list.
I'm fairly new to the C language, so if there's anything I'm misunderstanding please let me know.
#include "terminal_user_input.h"
#include <stdio.h>
#include <string.h>
enum musicGenre {Pop, Alternative_Rock, Electronic, Undefined};
struct Album
{
my_string Title;
my_string Artist;
int Year;
enum musicGenre Genre;
};
my_string PrintGenre(int Genre)
{
//Variables
my_string result;
printf("%d", Genre); //outputs correctly
switch (Genre)
{
case 0:
strcpy(result.str, "Pop");
case 1:
strcpy(result.str, "Alternative Rock");
case 2:
strcpy(result.str, "Electronic");
default:
strcpy(result.str, "Undefined");
}
return result;
}
int main()
{
// Variables
struct Album Album1;
int choice;
printf("1. Pop\n");
printf("2. Alternative Rock\n");
printf("3. Electronic\n");
choice = read_integer("Please select a genre: ");
switch (choice)
{
case 1:
Album1.Genre = 0;
break;
case 2:
Album1.Genre = 1;
break;
case 3:
Album1.Genre = 2;
break;
default:
Album1.Genre = 3;
break;
}
printf("%d", Album1.Genre);
printf("The genre of Album 1 is %s", PrintGenre(Album1.Genre).str);
return 0;
}
In your code,
switch (Genre)
{
case 0:
strcpy(result.str, "Pop");
case 1:
strcpy(result.str, "Alternative Rock");
case 2:
strcpy(result.str, "Electronic");
default:
strcpy(result.str, "Undefined");
}
all the case statements bodies are missing a break; statement, which makes it a fall-through switch.
To avoid this "undesired" behaviour, you need to add a break; statement every time you want to limit the flow of program to a certain part of the body.
Quoting the example from the C11 standard, chapter ยง6.8.4.2/P7
EXAMPLE In the artificial program fragment
switch (expr)
{
int i = 4;
f(i);
case 0:
i = 17;
/* falls through into default code */ << --- NOTE HERE
default:
printf("%d\n", i);
}
add break;
switch (Genre)
{
case 0:
strcpy(result.str, "Pop"); break;
case 1:
strcpy(result.str, "Alternative Rock"); break;
case 2:
strcpy(result.str, "Electronic"); break;
default:
strcpy(result.str, "Undefined");
}

Getting choice from input

I want to prompt the user to press a key.This key will be stored in a variable and a switch statement is applied on the key to execute the corresponding command.I wrote a code,which seems a bit nasty and inefficient because it makes a call to the function GetAsyncKeyState in an exhausting way,specially if the keys are too many.Is there a simpler approach to this?
#include <stdio.h>
#include <Windows.h>
int GetChoice(int *keys,size_t size);
int main(void)
{
int keys[] = {'A','B','F'};
int cKey = GetChoice(keys,3);
switch(cKey)
{
case 'A':
puts("you pressed : A!");
break;
case 'B':
puts("you pressed : B!");
break;
case 'F':
puts("you pressed : F!");
break;
}
Sleep(2000);
return 0;
}
int GetChoice(int *keys,size_t size)
{
size_t n;
while(1)
{
for(n = 0 ; n < size ; n++)
{
if(GetAsyncKeyState(keys[n]))
return keys[n];
}
}
return 0;
}
Well you need to only change from
int cKey = GetChoice(keys,3);
to
char cKey;
cKey=getch();
you do not need the
int GetChoice(int *keys,size_t size)
function. Just remove it too. Your entire code should look like
#include <stdio.h>
#include<conio.h>
int main(void)
{
char cKey;
cKey=getch();
switch(cKey)
{
case 'A':
puts("you pressed : A!");
break;
case 'B':
puts("you pressed : B!");
break;
case 'F':
puts("you pressed : F!");
break;
}
Sleep(2000);
return 0;
}
You are mixing apples and oranges. If you output messages with puts(), you should probably read input from standard input with getchar(). Reading the keyboard state with GetAsyncKeyState() is only consistent if you display information on the screen using the Windows API. Doing this in C has gone out of fashion a long time ago already. Good luck!
If you're trying to program in C, use C constructs, not Windows constructs. Take a look at K&R (Kernighan and Ritchie) section 1.5. K&R is available in PDF form. Just search for it.
If you use the async key state, you will have to apply your own detection for liftoff.

The invalid choice in the code appears in the output screen

Why does the "Invalid" appear in my output under everything? The invalid choice is the last thing in the menu, am I'm using the statement right or what exactly is wrong?
#include <stdio.h>
void two_assesments();
void three_assesments();
void four_assesments();
void five_assesments();
void six_assesments();
int main( void )
{
int c;
printf("\n*****Student Grade Calculator*****\n\n");
printf(" Developed By...\n");
printf(" Carlos\n");
printf(" University of South Wales\n");
printf(" =================================================================\n");
printf("\n");
printf("\n Please enter the number of assessments in the module : \n");
scanf("%d",&c);
if (c==2) {
two_assesments();
}
if (c==3) {
three_assesments();
}
if (c==4) {
four_assesments();
}
if (c==5) {
five_assesments();
}
if (c==6) {
six_assesments();
}
else
if (c=!7); {
{ printf("\nInvalid"); }
}
return(0);
}
The problem is here
else
if (c=!7); { . . .
You have a ; after if ()
I would suggest you use a switch statement like this
switch (c) {
case 2: two_assesments(); break;
case 3: three_assesments(); break;
case 4: four_assesments(); break;
case 5: five_assesments(); break;
case 6: six_assesments(); break;
default: printf("\nInvalid\n");
}
to make your code more readable.
To understand the problem, consider what happens if the user enters 2. The first if statement evaluates true and the two_assesments function is called. The next three if statements fail. Then we get to the if (c==6). That also fails, so the else is evaluated. And here you have two problems.
First is the semi-colon. Because you have a semicolon after the if (c=!7) the compiler sees your code as
if (c==6) {
six_assesments();
}
else {
if (c=!7)
; /* do nothing */
}
printf("\nInvalid");
In other words, because of the semicolon, the final if statement has no effect, and the printf isn't even part of the else. So "Invalid" always gets printed.
The other problem is the =!. What you meant to say was if (c!=7). By reversing the = and the !, you actually assign 0 to c, and the if always evaluates to false. The compiler should be giving you a warning about that.
A slightly improved version of the code would look like this
if (c==2)
two_assesments();
else if (c==3)
three_assesments();
else if (c==4)
four_assesments();
else if (c==5)
five_assesments();
else if (c==6)
six_assesments();
else
printf("\nInvalid");

How would I output to a file using multiple chars

#define numeric_b '0'
#define numeric_e '9'
/** init string intervals ---*/
static char c0=numeric_b;
static char c1=numeric_b;
static char c2=numeric_b;
static char c3=numeric_b;
static char c4=numeric_b;
static char c5=numeric_b;
static char c6=numeric_b;
static char c7=numeric_b;
/** init start & end ----------------*/
static const char en = numeric_e +1;
static const char st = numeric_b +1;
void str_in(int length){
FILE * fp = fopen("list.txt","w");
switch(length){
case 0:
printf("%c\n",c0);break;
case 1:
printf("%c%c\n",c0,c1);break;
case 2:
printf("%c%c%c\n",c0,c1,c2);break;
case 3:
printf("%c%c%c%c\n",c0,c1,c2,c3);break;
case 4:
printf("%c%c%c%c%c\n",c0,c1,c2,c3,c4);break;
case 5:
printf("%c%c%c%c%c%c\n",c0,c1,c2,c3,c4,c5);break;
case 6:
printf("%c%c%c%c%c%c%c\n",c0,c1,c2,c3,c4,c5,c6);break;
case 7:
printf("%c%c%c%c%c%c%c%c\n",c0,c1,c2,c3,c4,c5,c6,c7);break;
}
fclose(fp);
}
void permute(int length){
while(c0<=en){
str_in(length);
c0++;
if(c0==en && length==0){break;}
if(c0==en){
c0=st;
c1++;
if(c1==en && length==1){break;}
if(c1==en){
c1=st;
c2++;
if(c2==en && length==2){break;}
if(c2==en){
c2=st;
c3++;
if(c3==en && length==3){break;}
if(c3==en){
c3=st;
c4++;
if(c4==en && length==4){break;}
if(c4==en){
c4=st;
c5++;
if(c5==en && length==5){break;}
if(c5==en){
c5=st;
c6++;
if(c6==en && length==6){break;}
if(c6==en){
c6=st;
c7++;
if(c7==en && length==7){break;}
}
}
}
}
}
}
}
}
}
Sorry #zartag but this is some seriously obfuscated code. Please just tell us in a paragraph what you're trying to do and what you think your code is doing.
The most obvious thing I can see wrong with your code with respect to the question title ("output to a file") is that you are using printf instead of fprintf. They behave almost identically, except that printf prints to standard output, and fprintf prints to a file stream (e.g. to your list.txt). See the documentation on fprintf. In your case it should be
FILE * fp = fopen("list.txt","w");
switch(length){
case 0:
fprintf(fp, "%c\n",c0);break;
..snip
But seriously that code is in dire need of refactoring (e.g. it looks like the whole switch block can be replaced with a for loop). And please, when you ask a question here, give us a little more to go on than a code listing and question title.

Resources