Iterate through main function in C? - c

Here is my main function:
int main(int argc, char **argv)
{
LoadFile();
Node *temp;
char *key;
switch (GetUserInput())
{
case 1:
temp = malloc(sizeof(Node));
printf("\nEnter the key of the new node: ");
scanf("%s", temp->key);
printf("\nEnter the value of the new node: ");
scanf("%s", temp->value);
AddNode(temp);
free(temp);
break;
case 2:
key = malloc(sizeof(char *));
printf("Enter the key of the node you want to delete: ");
scanf("%s", key);
DeleteNode(key);
free(key);
break;
case 3:
PrintAll();
break;
case 4:
SaveFile();
break;
case 5:
return 0;
break;
default:
printf("\nWrong choice!\n");
break;
}
return 0;
}
The only problem with it is that after any case statement breaks, the program just exits out. I understand why, but I don't know how to fix it. I want the program to repeat itself each time even after the case statements. Would I just say:
main(argc, argv);
before every break statement?

wrap it in a while(1) { }
eg
while(1)
{
//switch... etc down to the close of the switch
}

After you reach a break statement control resumes at the end of the switch statement, so wrapping the entire switch in a while loop will make it repeat, but I would make it a separate function called from a loop in main:
void GetUserInput() {
// switch
}
int main()
{
while (1)
GetUserInput();
return 0;
}

Related

How to go back from switch menu

I want to make a menu that classifies animals into insects, birds, mammals and fishes with specific characteristics for each of these (using composite variables). I thought I'd use a nested switch case(one switch for the category of the animals and another switch for each category to perform the actions). The problem is, after I've entered a new entry for instance, I wanna have the option to go back and pick another action or even go back and pick another category. How can I do that? I tried with a do-while but I'm just getting an endless loop.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct{
unsigned int noLegs, lifeSpan;
char *name;
}insect;
typedef struct{
float speed, length;
char *habits, *name;
}bird;
typedef struct{
float weight, height;
char *food, *name;
}mammal;
typedef struct{
float weight, depth, salt;
char *name;
}fish;
int main(int argc, char **argv)
{
char choice, action;
bool running = true;
bool returnBack = true;
insect *i = (insect *)malloc(sizeof(insect));
if(!i)
{
printf("Failed to allocate memory.\n");
return -1;
}
while(running)
{
printf("Please choose a category:\n");
printf("1. Insects\n2. Birds\n3. Mammals\n4. Fishes\n5. Exit\n");
scanf(" %c", &choice);
switch(choice)
{
case '1':
printf("You've chosen: Insects\n");
while(returnBack)
{
printf("Please choose an action:\n");
printf("a. Add entry\nb. Delete entry\nc. Replace entry\nd. Lookup entries\ne. Back\n");
scanf(" %c", &action);
switch(action)
{
case 'a':
printf("What entry would you like to add?\n");
i->name = (char *)malloc(sizeof(char));
scanf("%s", i->name);
printf("How many legs does a %s have?\n", i->name);
scanf("%u", &(i->noLegs));
printf("What is the lifespan of a %s?\n", i->name);
scanf("%u", &(i->lifeSpan));
break;
case 'b':
printf("Which entry would you like to delete?\n");
break;
case 'c':
printf("Which entry would you like to replace?\n");
break;
case 'd':
printf("Which entry would you like to replace?\n");
break;
case 'e':
returnBack = false;
break;
default:
printf("Invalid action.\n");
}
}
break;
case '2':
printf("You've chosen: Birds\n");
break;
case '3':
printf("You've chosen: Mammals\n");
break;
case '4':
printf("You've chosen: Fishes\n");
break;
case '5':
running = false;
break;
default:
printf("Invalid choice.\n");
}
}
return 0;
}
As said by alex01011, you just need a while over the whole switch
When the user selects 5 running becomes FALSE and the loop exits.
One thing though, you forgot to clear the whitespace in the first scanf()
#include <stdio.h>
#include <stdlib.h>
#define TRUE (1==1)
#define FALSE (!TRUE)
/* ...
* ALL THE STRUCTS
*/
int main(int argc, char **argv)
{
char choice, action, running = TRUE;
insect *i = (insect *)malloc(sizeof(insect));
// CHECK ON MALLOC RETURN
while(running)
{
printf("Please choose a category:\n");
printf("1. Insects\n2. Birds\n3. Mammals\n4. Fishes\n5. Exit\n\n");
scanf(" %c", &choice); // <-- The leading space was missing
switch(choice)
{
/* ...
* PREVIOUS CASES
*/
case '5':
running = FALSE;
break;
default:
printf("Invalid choice.\n");
}
}
return 0;
}

switch case not working with character value if i input char value the switch doesn't encounter default and starts linfinite loop

---------- > ## Heading ## > when i input a character as an input default case of switch doesn't encounter and loop started > infinite times > > > enter code here
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void create();
void display();
void search();
struct node {
int data;
struct node* link;
};
struct node* head;
int main()
{
int value;
while (1) {
printf("Enter Correct Choice :- \n");
printf("Enter 1 to Create Linklist :- \n");
printf("Enter 2 to Display Linklist :- \n");
printf("Enter 3 to Search Linklist :- \n");
printf("Enter Your Choice Here _________ ");
scanf(" %d", &value);
switch (value) {
case 1:
create();
break;
case 2:
display();
break;
case 3:
search();
break;
default:
printf("Error !! Wrong Choice :- \n");
break;
}
}
return 0;
}
TL;DR- Always check the return value of scanf() for success.
In case of a non-numeric character input, the format specifier %d does not find a match, and no input is consumed (i.e., the invalid input remains in the input buffer). Thus, the switch body executes, most likely it does not find a match with any existing case statement, so the default case statement(s) get executed, and control goes back to while loop.
Then, due to the presence of the invalid input in the buffer (and not getting consumed), the above phenomena keeps on repeating.
The major problem is, in case of scanf() failure, the value of variable value remains uninitialized and indeterminate. It does not construct a well-defined program.
Couple of things:
Always initialize local variables.
Always check for success of scanf() before using the returned value, if you have to use scanf(). For better use fgets() to take user input.
In case of failure of input using scanf(), clean up the input buffer before trying to read next input.
The break causes the program to exit the switch case but not the while. To wxit the while as well you should do something like this:
#include <stdio.h>
#include <stdlib.h>
int main()
{
int value;
int done = 0;
while (!done) {
printf("Enter Correct Choice :- \n");
printf("Enter 1 to Create Linklist :- \n");
printf("Enter 2 to Display Linklist :- \n");
printf("Enter 3 to Search Linklist :- \n");
printf("Enter Your Choice Here _________ ");
scanf(" %d", &value);
switch (value) {
case 1:
printf("do stuff\n");
break;
case 2:
printf("do stuff\n");
break;
case 3:
printf("do stuff\n");
break;
default:
printf("Error !! Wrong Choice :- \n");
done = 1;
break;
}
}
return 0;
}
Here I used a variable initialized to 0 which indicates that the operation is not completed yet. When it's time to exit, the variable is set to 1, which causes the program to exit the while loop
Also, always remember to check the return value of printf(), to avoid possible errors
There is no break condition for while().
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
void create();
void display();
void search();
struct node {
int data;
struct node* link;
};
struct node* head;
int main()
{
int value = 1;
while (value) {
printf("Enter Correct Choice :- \n");
printf("Enter 1 to Create Linklist :- \n");
printf("Enter 2 to Display Linklist :- \n");
printf("Enter 3 to Search Linklist :- \n");
printf("Enter 0 to exit :- \n");
printf("Enter Your Choice Here _________ ");
scanf(" %d", &value);
switch (value) {
case 1:
create();
break;
case 2:
display();
break;
case 3:
search();
break;
default:
printf("Error !! Wrong Choice :- \n");
break;
}
}
return 0;
}
if a non valid integer is enter for scanf(" %d", &value); value is not set and the invalid input is not flush => scanf will never block nor update value
you need to check scanf returns 1 (you read 1 value) and if not to flush the invalid input for instance reading all the line
so you can replace
scanf(" %d", &value);
switch (value) {
...
}
by
if (scanf("%d", &value) != 1) {
puts("invalid input");
while ((value = getchar()) != '\n') {
if (value == EOF) {
puts("EOF, exit");
exit(-1);
}
}
}
else {
switch(value) {
...
}
}
of course you can also manage the invalid input in your default case forcing an invalid value :
if (scanf("%d", &value) != 1) {
while ((value = getchar()) != '\n') {
if (value == EOF) {
puts("EOF, exit");
exit(-1);
}
}
value = -1; /* any value except 1,2 or 3 */
}
switch(value) {
...
}
Out of that you have no option to stop the execution, you can do :
...
puts("Enter 4 to exit :-);
...
switch (value) {
...
case 4:
exit(0);
...
}
I belive your intention is to run the program as long as "0" is not entered, but ter is no case for "0". also when we have scanf for %d and entering a "char" instead scanf will not read the char from buff. data on value will not get changed and it will keep printing existing data. (garbage if we enter invalid data first time itself, or any entered data.)
used fgets to read the input data, and do a scanf from buf, even when data is incorrect we are clearing the std input. so program will not get in to a infinite loop with scanf failure.
initilised "value = 0"
added case for "0".
scanf is replaced with fget +sscanf
#include <stdio.h>
#include <stdlib.h>
int main()
{
int value = 0;
char buff[256] = {0};
while (1) {
value = -1;
printf("Enter Correct Choice :- \n");
printf("Enter 1 to Create Linklist :- \n");
printf("Enter 2 to Display Linklist :- \n");
printf("Enter 3 to Search Linklist :- \n");
printf("Enter Your Choice Here _________ ");
fgets(buff, 255, stdin);
sscanf(buff, "%d", &value);
switch (value) {
case 1:
//create();
printf("case : 1\n");
break;
case 2:
//display();
printf("case : 2\n");
break;
case 3:
//search();
printf("case : 3\n");
break;
case 0 :
printf("case : 0 : Exiting program\n");
return 0;
default:
printf("Error !! Wrong Choice :- %d\n", value);
break;
}
}
return 0;
}

c program function not working properly

#include<stdio.h>
#include<string.h>
void createIndexFile(char[]);
int main()
{
FILE *fp;
char fname[40];
int option;
printf("\nEnter the filename to open: ");
scanf("%s",fname);
fp=fopen(fname,"r");
if(fp==NULL)
{
printf("\nCannot open the file\n");
return 0;
}
else
{
printf("\n%s",fname);
createIndexFile(fname);
}
while(1)
{
printf("\n*****MENU*****\n");
printf("\n1.Display ......\n2.Insert new data\n3.Find data\n4.Display data\n5.Exit\n");
printf("\nChoose an operation: ");
scanf("%d",&option);
switch(option)
{
case 1: break;
case 2: break;
case 3: break;
case 4: break;
case 5: return 0;
default: printf("\nInvalid selection\n");
}
}
}
void createIndexFile(char fname[])
{
int i=0;
char tempFile[40];
char indexFile[40];
printf("\n%s",fname);
strcpy(indexFile,"xyz");
strcpy(tempFile,fname);
while(tempFile[i]!='.')
{
if(tempFile[i]=='/')
tempFile[i]='_';
}
strcat(tempFile,".idx");
strcat(indexFile,tempFile);
printf("\nIndex File Name: %s",indexFile);
}
It is a program where after a filename is entered suppose /home/abc.txt and my name is xyz then an index file should be created xyz_home_abc.idx.
After the filename is entered and if it is present, it should go to else part and function
createIndexFile(fname);
should be called. But inside the function, nothing is working properly. If we print a character or something, it is printed. But if I try to give another printf it is not working.
Corrected your function
void createIndexFile(char fname[])
{
int i=0;
char tempFile[40];
char indexFile[40];
printf("\n%s",fname);
strcpy(indexFile,"");
while(fname[i]!='.')
{
if(fname[i]=='/')
tempFile[i]='_';
else
tempFile[i]=fname[i];
i++;
}
tempFile[i]='\0';
strcat(tempFile,".idx");
strcat(indexFile,tempFile);
printf("\nIndex File Name: %s",indexFile);
}

switch menu in C

I'm trying to use a menu in this C program but I keep getting an error:
3.c: In function 'main':
q3.c:99:3: error: expected declaration or statement at end of input
}
^
q3.c:99:3: error: expected declaration or statement at end of input
The code
#include <stdio.h>
int userInput();
void printList();
void editStud();
void delStud();
void addStud();
struct studentRec
{
char name[25];
char init[25];
char pNu[25];
int studNum;
float bBalance;
};
int main()
{
//no constants
struct studentRec students;
FILE *fp,*fw,*ft;
int sel = 1; //select number for menu
while(userInput)
{
sel = userInput();
switch(sel)
case1:
printList();
break;
case2:
editStud();
break;
case3:
delStud();
break;
case4:
addStud();
break;
case0:
break;
{
}
int userInput()
{
int choice;
printf("===========================\n");
printf("(1). View all students\n");
printf("(2). Edit student details\n");
printf("(3). Delete student\n");
printf("(4). Add new student\n");
printf("(0). Exit\n");
printf("===========================\n\n");
printf("Enter your choice Please\n");
scanf("%d", &choice);
return choice;
}
void printList()
{
printf("*Prints list*\n");
}
void editStud()
{
printf("*edits entry*\n");
}
void delStud()
{
printf("*deletes entry*\n");
}
void addStud()
{
printf("*adds entry\n");
}
Thanx for all the responses, what I meant to do:
.
.
.
int userInput();
void printList();
void editStud();
void delStud();
void addStud();
.
.
.
int sel = 1; //select number for menu
while(sel)
{
sel = userInput();
switch(sel)
{
case 1:
printList();
break;
case 2:
editStud();
break;
case 3:
delStud();
break;
case 4:
addStud();
break;
case 0:
break;
default:
printf("That is not a valid selection!\n");
}
}
.
.
.
errors were:
1. incorrect while braces
2. used while(userInput) instead of while(sel)
3. no space between case and number
what is case1? My only guess is that you mean to compare against 1, in which case you'd have to leave a space between the keyword case and the actual case value. Here's how your switch case should look like:
switch (sel) {
case 1:
printList();
break;
case 2:
editStud();
break;
case 3:
delStud();
break;
case 4:
addStud();
break;
case 0:
break;
}
1) Your braces inside while is meaningless (the one before ending while brace)
2) your switch statement does not have enclosing braces.
3) Also, there should be a space between case keyword and the switch input
Correct way is
while(userInput){
sel = userInput();
switch(sel){
case 1:
printList();
break;
case 2:
editStud();
break;
case 3:
delStud();
break;
case 4:
addStud();
break;
case 0:
break;
}
}
Change:
case1:
to
case 1:
etc.
also a switch statement requires a starting { and an ending }.
After a Switch statement, you want a open brace.
switch(sel) {
case is a keyword, which means that you probably want whitespace around it.
case 1:
case 2:
...
You have an open brace where you probably want a close brace. The number of open braces should match the number of close braces.
}
Your while statement is quite odd. You probably want to do something else with that...
So, main() should actually look like:
int main()
{
struct studentRec students;
FILE *fp,*fw,*ft;
int sel = 1; //select number for menu
while(true)
{
sel = userInput();
switch(sel) {
case 1:
printList();
break;
case 2:
editStud();
break;
case 3:
delStud();
break;
case 4:
addStud();
break;
case 0:
break;
}
}
}

C program switch statement

I'm new to programming in C. I have a quick question about Switch Statements.
I have a menu that presents a list of options like so:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define MAX 100
struct Video {
char name[1024]; // Yvideo name
int ranking; // Number of viewer hits
char url[1024]; // YouTube URL
};
struct Video Collection[MAX];
int tail = 0;
//-- Forward Declaration --//
void printall();
void insertion();
void savequit();
void load();
void branching(char);
void menu();
int main()
{
char ch;
load(); // load save data from file
printf("\n\nWelcome\n");
do {
menu();
fflush(stdin); // Flush the standard input buffer
ch = tolower(getchar()); // read a char, convert to lower case
branching(ch);
} while (ch != 'q');
return 0;
}
void menu()
{
printf("\nMenu Options\n");
printf("------------------------------------------------------\n");
printf("i: Insert a new favorite\n");
printf("p: Review your list\n");
printf("q: Save and quit\n");
printf("\n\nPlease enter a choice (i, p, or q) ---> ");
}
void branching(char option)
{
switch(option)
{
case 'i':
insertion();
break;
case 'p':
printall();
break;
case 'q':
savequit();
break;
default:
printf("\nError: Invalid Input. Please try again...");
break;
}
}
so far entering 'i' (for inserting a new entry) and q (for save and quit) work perfectly. However every time I enter 'p' I get the default case. (Error: Invalid Input. Please try again...). What is it that I am doing wrong? I believe the syntax for the switch is correct? I've tried changing the 'p' to a different letter and I still got the the default case. Here is my printall() method if that helps...
void printall()
{
int i;
printf("\nCollections: \n");
for(i = 0; i < tail; i++)
{
printf("\nName: %s", Collection[i].name);
printf("\nRanking (Hits): %d", Collection[i].ranking);
printf("\nURL: %s", Collection[i].url);
printf("\n");
}
}
What about something like:
char b[5];
do {
menu();
if(fgets(b,5,stdin)==NULL)
return -1;
ch = tolower(b[0]); // read a char, convert to lower case
while(strlen(b)>=4&&b[3]!='\n'){
check=fgets(b,5,stdin);
if(check==NULL)
return -1;
}
branching(ch);
} while (ch != 'q');
You can output the invalid char in your default case. That may help you understand how your input are handled.
default:
printf("\nError: Invalid Input ('%c'). Please try again...", option);
break;
fflush(stdin) is undefined as fflush is define only for output streams. To clear the newline char, you can simply use another getchar().
Try this for the loop part:
do {
menu();
ch = tolower((unsigned char)getchar());
getchar();
branching(ch);
} while (ch != 'q');

Resources