My program's structure is like this:
main function has a menu (switch) between two other functions.
One of them is just a calculation and when it ends it goes back to this (main) menu.
Which is exactly what I want now (earlier I wanted to end the program after calculation and I had exit(0); in all cases.
But the other function is tricky because it starts another function (menu) and there are two options of calculations. One of them also has another switch.
The problem is when I edited codes which look like this by removing exit(0);
case 'H':
rhdp(0,n_hdp0, fw_vystup);
vyprazdni_buffer(); //buffer clearing
exit(0);
break;
It only works for the simple calculation but deeper parts of the program only go one step back...
Any possible solutions? Thanks in advance.
here is more of a code
void nhdp_menu(float cislo, FILE **fw_vystup)
{
char c;
float y, n_hdp0 = 0.0f, n_hdp1 = 0.0f;
do {
printf("Zadejte nominalni hruby domaci produkt daneho roku: ");
zadani_cisla(&cislo);
n_hdp1 = cislo;
} while (n_hdp1 <= 0);
do {
printf("Zadejte nominalni hruby domaci produkt predesleho roku: ");
zadani_cisla(&cislo);
n_hdp0 = cislo;
} while (n_hdp0 <= 0);
y = (n_hdp1 - n_hdp0) / n_hdp0 * 100;
printf("Tempo rustu nominalniho HDP je %f procent.\n", y);
zapis(fw_vystup, "Nominalni HDP0 = %f ; Nominalni HDP1 = %f ; Tempo rustu nominalniho HDP je %f procent.\n", n_hdp0, n_hdp1, y);
do {
printf("Dodatecne muzete take zjistit tempo rustu REALNEHO HDP:\n");
printf("Pokud znate deflator HDP v danem roce - zadejte D.\n");
printf("Pokud znate primo realne HDP v danem roce - zadejte H.\n");
vyprazdni_buffer();
scanf("%c", &c);
switch (c) { //this is the last (deepest) switch
case 'd':
case 'D':
rhdp_ipd(0, n_hdp0, n_hdp1, fw_vystup);
vyprazdni_buffer();
//exit(0);
break;
case 'h':
case 'H':
rhdp(0,n_hdp0, fw_vystup);
vyprazdni_buffer();
//exit(0);
break;
case 'k':
case 'K':
printf("Konec programu.\n");
break;
default:
printf("Neznama volba.\n");
break;
}
} while (c != 'k' && c != 'K');
return;
}
void tempo_menu(n_hdp0)
{
FILE *fw_vystup;
char c;
do {
printf("Vyberte si, v jakych cenach chcete HDP uvadet.\nPro nominalni zadejte N.\nPro realne zadejte R.\n");
scanf("%c", &c);
vyprazdni_buffer();
switch (c) {
case 'N':
case 'n':
nhdp_menu(0, &fw_vystup); //this here is starting another menu
vyprazdni_buffer();
//exit(0);
break;
case 'R':
case 'r':
rhdp(0, 0, &fw_vystup);
vyprazdni_buffer();
//exit(0);
break;
case 'k':
case 'K':
printf("Konec programu.\n");
break;
default:
printf("Neznama volba.\n");
break;
}
} while (c != 'k' && c != 'K');
return;
}
int main(void)
{
char c;
FILE *fw_vystup;
do {
printf("Zadejte D pro vypocet deflatoru HDP nebo T pro vypocet tempa rustu HDP: ");
scanf("%c", &c);
vyprazdni_buffer();
switch (c) {
case 'd':
case 'D':
deflator(0, &fw_vystup); //for this function everything goes well
// exit(0);
vyprazdni_buffer();
break;
case 't':
case 'T':
tempo_menu();
vyprazdni_buffer();
// exit(0);
break;
case 'k':
case 'K':
printf("Konec programu.\n");
break;
default:
printf("Neznama volba.\n");
break;
}
} while (c != 'k' && c != 'K');
return 0;
}
EDIT:
So this is assuming you're put return in all the case statements because this is the behavior you want.
The problem with main not printing until you press some keys. Try using fflush(stdout) in your main function:
int main(void)
{
char c;
FILE *fw_vystup;
do {
printf("Zadejte D pro vypocet deflatoru HDP nebo T pro vypocet tempa rustu HDP: ");
scanf("%c", &c);
vyprazdni_buffer();
switch (c) {
case 'd':
case 'D':
deflator(0, &fw_vystup); //for this function everything goes well
vyprazdni_buffer();
break;
case 't':
case 'T':
tempo_menu();
vyprazdni_buffer();
break;
case 'k':
case 'K':
printf("Konec programu.\n");
break;
default:
printf("Neznama volba.\n");
break;
}
fflush(stdout); // <--- right here.
} while (c != 'k' && c != 'K');
return 0;
}
Related
here is a demo code for explaining what I'm actually looking for
I want to call a 'case' of "switch" - statement from somewhere else in the code in C Language.
Here is the source code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
char a;
int main()
{
printf("Enter a number: ");
scanf("%c", &a);
switch(a){
case 'a':
printf("This is for A & C");
break;
case 'b':
printf("This is for only B");
break;
case 'c':
// Here i want to call "case 'a':"
goto case 'a';
// how can a call another case here?
break;
default:
printf("Default");
break;
}
getch();
return 0;
}
Thanks is Advance :D
You need the so-called "fall-through" case:
So instead of this:
case 'a':
printf("This is for A & C");
break;
case 'b':
printf("This is for only B");
break;
case 'c':
// Here i want to call "case 'a':"
Write this:
case 'a':
case 'c':
printf("This is for A or C");
break;
case 'b':
printf("This is for only B");
break;
I want to write a program that converts integer to another char and print them. I expect to work but It didn't work anyway even if I want to print same integer without converting.
My code is here:
#include<stdio.h>
int main()
{
FILE *fp;
int a;
fp=fopen("deneme.txt", "r");
while(feof(fp)) {
fscanf(fp,"%d",&a);
switch(a) {
case 0:
printf(" ");
break;
case 1:
printf("-");
break;
case 2:
printf("_");
break;
case 3:
printf("|");
break;
case 4:
printf("/");
break;
case 5:
printf("\\");
break;
case 6:
printf("O");
break;
default:
break;
}
}
}
My txt is that:
while(Game == 0)
{
gotoxy(100,40);
setForeColor(MY_COLOR_WHITE);
printf("A- Jogar uma partida de Anabi\n");
gotoxy(100,42);
printf("B- Carregar partida anterior\n");
gotoxy(100,44);
printf("C- Descri%c%co do jogo\n", 135, 198);
gotoxy(100,46);
printf("D- Sair do jogo\n");
scanf("%c", &choice);
switch(choice)
{
//This part of the code should break my loop
case 'A':
case 'a':
gotoxy(100, 52);
printf("Please enter your name bellow\n");
gotoxy(98, 53);
printf("->");
scanf("%s",NamePlayer);
Game = 1;
break;
case 'B':
case 'b':
// in here I am going to call a function, the function that reads the file previously saved
//also here I am going to know if there is any saved files, and give an output to the user
break;
case 'C':
case 'c':
//This gets me to the description of the game, rules, etc.. and its working fine with the loop
DescricaoDoJogo();
break;
case 'D':
case 'd':
exit(0);
break;
default:
//This default is giving me trouble, should I use and If, else? Because when i choose the option C, and I get back to the menu what is inside the default executes
printf("Wrong choice.. Try again.. A, B, C or D..");
scanf(" %c", &choice);
system("cls");
break;
}
}
When I enter the letter 'q' as grade, it runs infinitely.
#include <stdio.h>
#include <stdbool.h>
int main(void) {
int grade;
bool flag = true;
while (flag) {
puts("-----------------------------"); // comment
printf("What's your grade out of 10? ");
scanf(" %d", &grade);
switch (grade) {
case 10:
case 9:
case 8:
case 7:
case 6:
printf("Pass\n");
break;
case 5:
printf("Fail\n");
break;
case 4:
printf("Fail\n");
break;
case 3:
printf("Fail\n");
break;
case 2:
printf("Fail\n");
break;
case 1:
printf("Fail\n");
break;
case 0:
printf("Fail\n");
break;
default:
printf("Illegal Grade\n");
flag = false;
break;
}
}
return 0;
}
scanf(" %d",&grade);
It scans int in string. "q" is not int. When you enter "q", value of the variable grade left unchanged. You must check returned value of scanf to validate number of filled placeholders.
if (scanf(" %d",&grade) != 1) {
printf("Illegal Grade\n");
exit(1); // or break
}
Other parts are ok.
scanf(" %d", &grade); fails when you type something that cannot be parsed as into an integer. grade is not modified, so it is uninitialized if the conversion error happens immediately and the behavior is undefined, otherwise you get the same value and behavior as the previous time.
The offending input stays in the input stream, so the same thing happens when the code executes again in the while loop, hence the infinite loop.
You want to test if the conversion was successful and discard the input if not:
#include <stdio.h>
#include <stdbool.h>
int main(void) {
int res, c, grade;
bool flag = true;
while (flag) {
puts("-----------------------------"); // comment
printf("What's your grade out of 10? ");
res = scanf("%d", &grade);
if (res == EOF)
break;
if (res == 0) {
printf("Invalid input\n");
/* discard the offending line of input */
while ((c = getchar()) != EOF && c != '\n')
continue;
/* try again */
continue;
}
switch (grade) {
case 10:
case 9:
case 8:
case 7:
case 6:
printf("Pass\n");
break;
case 5:
case 4:
case 3:
case 2:
case 1:
case 0:
printf("Fail\n");
break;
default:
printf("Illegal Grade\n");
flag = false;
break;
}
}
return 0;
}
I'm making this program using switch statements that will assign letter grades based on if the user enters numbers 0 - 10. If the user enters a number that is not 0-10, the program outputs an error message and has the user re-enter. However, if the user enters a character the program will loop at the default case. I want it to output the error message from the default case once, and have them re-enter if they enter a character. I'm not sure as to why it loops the default case when a character is entered though.
#include <stdio.h>
int main()
{
int grade;
int r;
while((r = scanf("%i", &grade)) != EOF)
{
switch(grade)
{
case 10:
case 9:
printf("Your grade is an A\n");
break;
case 8:
printf("Your grade is a B\n");
break;
case 7:
printf("Your grade is a C\n");
break;
case 6:
printf("Your grade is a D\n");
break;
case 5:
case 4:
case 3:
case 2:
case 1:
case 0:
printf("Your grade is an F\n");
break;
default:
printf("Invalid score, please re-enter\n");
}
}
return 0;
}
Try something like:
#include <stdio.h>
int main()
{
int grade;
int r=0;
while(r != 1)
{
scanf("%i", &grade);
switch(grade)
{
case 10:
case 9:
printf("Your grade is an A\n");
r=1
break;
case 8:
printf("Your grade is a B\n");
r=1
break;
case 7:
printf("Your grade is a C\n");
r=1
break;
case 6:
printf("Your grade is a D\n");
r=1
break;
case 5:
case 4:
case 3:
case 2:
case 1:
case 0:
printf("Your grade is an F\n");
r=1
break;
default:
printf("Invalid score, please re-enter\n");
break;
}
}
return 0;
}
This will clear the input buffer on an invalid input and allow a retry.
#include <stdio.h>
int main()
{
int grade;
int r;
while((r = scanf("%i", &grade)) != EOF)
{
if ( r != 1) {//r == 1 is successful input of integer
grade = -1;//reset grade on invalid input
}
switch(grade)
{
case 10:
case 9:
printf("Your grade is an A\n");
break;
case 8:
printf("Your grade is a B\n");
break;
case 7:
printf("Your grade is a C\n");
break;
case 6:
printf("Your grade is a D\n");
break;
case 5:
case 4:
case 3:
case 2:
case 1:
case 0:
printf("Your grade is an F\n");
break;
default:
printf("Invalid score, please re-enter\n");
while ( getchar() != '\n');//clear input buffer
}
}
return 0;
}
The reason your code always loops is because there is no way to exit out of your while other than to kill the program. Remember that break only breaks out of the inner-most switch or loop.
The cleanest way to break out of multiple levels is to use a flag. One way to do what you want is like this:
bool valid_grade = false;
while(!valid_grade && (r = scanf("%i", &grade)) != EOF)
{
valid_grade = true;
switch(grade)
{
case 10:
// unchanged from your code
default:
valid_grade = false;
printf("Invalid score, please re-enter\n");
}
}