The invalid choice in the code appears in the output screen - c

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");

Related

Fixing C switch statement function overflow?

int main (void)
{
*/ function prototypes */
print_case();
do_something1();
do_something2();
do_something3();
do_something4();
exit_program();
program_invalid();
}
void print_case (void)
{
int i;
printf("\n"
"1. Do Something 1\n"
"2. Do Something 2\n"
"3. Do Something 3\n"
"4. Do Something 4\n"
"5. Exit the program\n"
"Enter choice (number between 1-5)>\n");
scanf("%d", &i);
switch(i)
{
case 1:
do_something1();
break;
case 2:
do_something2();
break;
case 3:
do_something3();
break;
case 4:
do_something4();
break;
case 5:
exit_program();
break;
default:
program_invalid();
break;
}
return;
}
something_t do_something1(void)
{
something_t something;
printf("Something 1\n");
return something;
}
void do_something2(something_t something)
{
printf("Something 2\n");
}
void do_something3()
{
printf("Something 3\n");
}
void do_something4()
{
printf("Something 4\n");
}
void exit_program (void)
{
exit(0);
}
void program_invalid (void)
{
printf("Not valid choice");
}
So basically when I compile it and execute the code and select the various cases, it will execute multiple functions at once and prints out multiple statements at once. Let's say I choose case 1 the output it prints Something 1 but when I choose case 2 it prints
Something 1
Something 2
and when I choose case 3 it prints
Something 1
Something 2
Something 3
So how would I fix my code to get out of the loop? I thought break statements would only let it execute one function at a time. Yes the something_t references to my typedef structures that I didn't include in my code.
print_case() has the switch. It does its thing then returns. What you THINK are function prototypes in main() are actually just calls. So it calls them. And so you see all of the functions executing. C has a habit of shrugging and making that work, because traditionally it is very tolerant. Move your 'prototypes' out to before main() and preferably put a proper signature on them all.
Your do_something2 has an arg, but you are not declaring it in the (non-working) fake prototype - that is, it will be incorrect once you move it out to before main().
Also, since you have declared do_something2() to take an arg, you'd better pass one!
why are you putting something_t as input into your function. The code your posting also will not compile.
you also have a gap in the name and are missing a function type for function something_t do_something1(void).
Here is the clean version of your code , I think this might help you remember some stuff.
#include <stdio.h>
#include <stdlib.h> // for exit.
#define True 1 // Symbolic constants.
/*
* This is a multi-line comment.
* -----------------------------
* These is how a function prototype
* should be.
* You can leave the parameter names
* empty because in function prototypes
* the parameter names are dumy but not
* the types.
*/
typedef int something_t; // You can have any structure here.
// just for an example.
void print_case(void);
something_t do_something1(void);
void do_something2(something_t);
void do_something3(void);
void do_something4(void);
void exit_program (void);
void program_invalid (void);
// ---- This is a single line comment.
int main()
{
while(True) {
print_case();
}
return 0;
}
void print_case (void)
{
int i;
printf("\n"
"1. Do Something 1\n"
"2. Do Something 2\n"
"3. Do Something 3\n"
"4. Do Something 4\n"
"5. Exit the program\n"
"Enter choice (number between 1-5)>\n");
scanf("%d", &i);
switch(i) {
case 1:
do_something1();
break;
case 2:
do_something2(True); // must pass your struct.
break;
case 3:
do_something3();
break;
case 4:
do_something4();
break;
case 5:
exit_program();
break;
default:
program_invalid();
break;
}
return;
}
something_t do_something1(void)
{
something_t something;
printf("Something 1\n");
return something;
}
void do_something2(something_t something)
{
printf("Something 2\n");
}
void do_something3(void)
{
printf("Something 3\n");
}
void do_something4(void)
{
printf("Something 4\n");
}
void exit_program (void)
{
exit(0);
}
void program_invalid (void)
{
printf("Not valid choice");
}

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.

Function A called out of function A?

I'm still a newbie in programming, but I'm trying to make a program that's slightly larger and consists in way more functions than usual. And I want to make a repeatable 'Main menu' (which from you can access the rest of program's functions), but when I'm trying to call out the function again, nothing's happening. It looks like this:
void mainMenu()
{
//clear console screen
//menu of the program
//i.e "Press 1 to choose something
//console screen is cleared again, then new options appear
//"Press E to go back to main menu"
unsigned char v;
v = getch();
if (v == 'E')
mainMenu();
}
What am I doing wrong? Shouldn't the mainMenu() be called out again, clear screen etc? I guess I could just return something from function which would cause the program to call mainMenu() again (and change mainMenu() to int for example), but there must be some workaround, which I'm missing.
You must add an option for exiting out of the loop too !
void mainMenu()
{
system( "cls" );
cout << "1. blah1\n2. blah2\n3. blah3\n4. Main menu\nE. Exit\n\n";
unsigned char v = getch();
if ( v == '1' )
{
cout << "blah1\n";
// Call procedure for blah1
}
else if ( v == '2' )
{
cout << "blah2\n";
// Call procedure for blah2
}
else if ( v == '3' )
{
cout << "blah3\n";
// Call procedure for blah3
}
else if ( v == '4' )
{
mainMenu();
}
if ( v == 'E' )
{
return;
}
}
int main()
{
mainMenu();
}
You mentioned that you are a newer to programming, but have you heard of the control structure in c++ called a switch/case statement? It might be suitable for the simple menu that you are trying to implement. You can read about it here.
A quick example in regards to your desired use case could look something like:
void mainMenu()
{
unsigned char v, w;
v = getch();
switch(v)
{
case 'E':
mainMenu();
break;
case 'A':
w = getch();
if (w == 1)
callFunctionA();
else
mainMenu();
break;
case 'B':
callFunctionB();
break;
// etc... You can have as many 'case' statements as you want depending on
// how many possibilities you want to handle on the user's input.
default:
break;
}
}
I would recommend implementing your function this way:
void mainMenu()
{
unsigned char v;
do
{
//clear console screen
//menu of the program
//i.e "Press 1 to choose something
//console screen is cleared again, then new options appear
//"Press E to go back to main menu"
v = getch();
} while (v == 'E'); // Repeat do-while-loop if user entered 'E'
}
Now there's no change for stack overflow, because there's no recursion involved.

can anyone find why is ths program to solve postfix expression giving runtime error

I was trying to solve a postfix expression but i don't understand why is it giving runtime error.
code:
#include<stdio.h>
#include<stdlib.h>
#include<stdlib.h>
struct stack
{
int top;
int n[100];
}s;
void push(int a)
{
s.n[s.top+1]=a;
s.top++;
}
void pop(char a)
{
int c,b;
b=s.n[s.top];
c=s.n[s.top-1];
s.top--;
switch(a)
{
case '+':
s.n[s.top]=b+c;
break;
case '-':
s.n[s.top]=b-c;
break;
case '*':
s.n[s.top]=b*c;
break;
case '/':
s.n[s.top]=b/c;
break;
}
}
int main()
{
s.top=-1;
int m,i,k;
char a[100],c[100];
scanf("%d",&m);
for(i=0;i<m;i++)
{
int j=0;
while(1)
{
scanf("%c",a[j]);
if(a[j]=='?')
break;
else if(a[j]==' ')
{
push(atoi(a));
}
else if(a[j]=='+'||'-'||'*'||'/')
{
pop(a[j]);
}
else
{
j++;
}
}
printf("%d",s.n[s.top]);
}
}
You code is hardly readble, still, I think, you need to change
scanf("%c",a[j]);
to
scanf(" %c",&a[j]); //note the space before %c, and scanf() expects pointer
for
& because as per the scanf() signature, it needs the address to store the scanned result.
leading space [] to stop scanning the previously pressed ENTER [\n] key.
Kindly Check the man page of scanf() for more details.
Also, as mentioned in Mr. #LPs 's answer, usage of push(atoi(a)); is very dangerous, in case a is not null-terminated.
Chnage scanf("%c",a[j]); to scanf("%c",&a[j]);. You need to pass the address to store the value of char. Also, you would further need to discard the extra character after each input from stdin.
I think that instruction push(atoi(a));is not safe, because of the array is not zero initialized, than atoi can fall into undefined behaviour.
Another thing is that with scanf with %c you can accept all chars (eg a, b,c) that make atoi fail.

C : strchr pointer value doesn't change

I'm trying to recursively search for a substring in a string using C program. I wrote the following piece of code. The issue I'm facing is that, the ptr value, though it prints the correct value(using puts in the beginning of while), while usage its value is not changed! It uses the previous ptr value. I found this out using gdb. I couldn't figure out the cause of this. Kindly guide me to solve this issue. Thanks in advance.
void main()
{
char buf[10]="hello",*ptr;
char findc[10]="lo";
int len,i,lenf,k,l,flag=0;
lenf=strlen(findc);
l=0,k=1;
ptr=strchr(buf,findc[l]);
while(ptr!=NULL)
{
puts(ptr);
l++;
for(i=l;i<(lenf);i++,k++)
{
if(ptr[k] != findc[i])
{
flag=1;
break;
}
}
if(flag==1)
{
l=0;k=1;
ptr=strchr((ptr+1),findc[l]);
if(ptr==NULL)
{
puts("String not found");
break;
}
}
else
{
puts("String found");
break;
}
}
}
It was a very simple mistake!
We'll have to reset the flag variable in the beginning of the while loop. This would solve the issue.
Thanks!

Resources