Fixing C switch statement function overflow? - c

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

Related

Passing and returning a struct from a function

I have a function with a book struct array, but when i try to return it to my main it does not return the values and store them in the array. If the addBook function has to be void how would i work around that so that i can access the array elements later.
void addBook(struct Book book[], int *size) {
if (*size == MAX_BOOKS) {
printf("The inventory is full\n");
}
else {
printf("ISBN:");
scanf("%d", &book[*size]._isbn);
printf("Title:");
scanf("%s", book[*size]._title);
getchar();
printf("Year:");
scanf("%d", &book[*size]._year);
printf("Price:");
scanf("%f", &book[*size]._price);
printf("Quantity:");
scanf("%d", &book[*size]._qty);
*size++;
printf("The book is successfully added to the inventory.\n");
}
return book;
}
int main(void) {
struct Book book[MAX_BOOKS];
int size = 0;
int i;
int option;
printf("Welcome to the Book Store\n");
printf("=========================\n");
do {
menu();
printf("Select: ");
scanf("%d", &option);
switch (option) {
case 0:
printf("Goodbye!\n");
break;
case 1:
displayInventory(book, size);
break;
case 2:
addBook(book, &size);
break;
case 3:
//checkPrice();
break;
default:
printf("Invalid input, try again:\n");
}
} while (option != 0);
}
Your return statement isn't going to do what you're intending as the addBook's function signature says it returns void. I'm surprised that the code as is actually compiled without an error about this.
Anyways, the book data can be returned from the same way it was passed in - as an input and output parameter.
Essentially your code could look like the following (which is only meant to be an example of code that compiles and works to save info entered in from standard input into the book):
#include <stdio.h>
struct Book {
int value;
};
#define MAX_BOOKS 2
void addBook(struct Book book[], int *size) {
if (*size == MAX_BOOKS) {
printf("The inventory is full\n");
}
else {
printf("Value:");
scanf("%d", &book[*size].value);
(*size)++;
printf("The book is successfully added to the inventory.\n");
}
}
int main(void) {
struct Book book[MAX_BOOKS];
int size = 0;
addBook(book, &size);
printf("Book 1: Value=%d\n", book[0].value);
}
And here's how this looks when run:
$ ./main
Value:9
The book is successfully added to the inventory.
Book 1: Value=9
Hope this answers your question.
I think your problem is in the line *size++;. You should use parenthesis, otherwise you are modifying the pointer to size, not the value. It should be (*size)++.
Also, the addBook function should not return anything, since it is void, and it is changing the content of the array book already.

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

Make functions call each other - C

A noob question: I created a library called funcoes.h that have a menu() and other functions that can call menu(). An example:
void cifrar(){
printf("\n\nDeseja cifrar outra mensagem? Digite 1 para Sim ou 2 para sair: ");
scanf("%d", &exit);
if(exit == 1){
cifrar();
}
else{
menu();
}
}
void menu(){
printf("Escolha uma das opcoes: ");
scanf("%d", &varMenu);
switch(varMenu){
case 1:
system("cls");
cifrar();
break;
case 2:
system("cls");
decifrar();
break;
case 3:
system("cls");
sair();
break;
default:
system("cls");
printf("Escolha uma opcao valida!\n\n");
menu();
break;
}
}
But when I compile, I have this error:
In function 'void cifrar()'
'menu' undeclared(first use this function)"
'void menu()' used prior to declaration
How to make them call each other without this error?
Thanks!
every function that you call has to be declared BEFORE that call. you can do this by using a prototype of that function:
void menu();
void cifrar() {
...
}
void menu() {
..
}
or simply by putting the whole main function (with it's body) on top of cifrar.
Well, maybe it would be nice to sum up what is in comments.
The compiler wants to know any function's prototype before this function is used somewhere else. 'Before' here means something like 'earlier in the source file'. You can, although, place all the prototypes in a separate .h file, include it in the .c file with actual code, and then place function implementations in whatever order you like - the compiler will not complain.
What you should do, is to create a header file, which will have the signatures of all your functions and then you do not need to worry about where each function is located at the code, you will be able to use all of the functions all over the code.
Your code should look like this:
funcoes.h
void cifrar(void);
void menu(void);
funcoes.c
#include "funcoes.h"
void cifrar(void){
printf("\n\nDeseja cifrar outra mensagem? Digite 1 para Sim ou 2 para sair: ");
scanf("%d", &exit);
if(exit == 1){
cifrar();
}
else{
menu();
}
}
void menu(void){
printf("Escolha uma das opcoes: ");
scanf("%d", &varMenu);
switch(varMenu){
case 1:
system("cls");
cifrar();
break;
case 2:
system("cls");
decifrar();
break;
case 3:
system("cls");
sair();
break;
default:
system("cls");
printf("Escolha uma opcao valida!\n\n");
menu();
break;
}
}
Another small tip, do not create functions without any arguments, such as:
void menu();
Always insert the arguments you want to pass. If you want the functions to get not arguments, just pass void.
void menu (void);

C/C++ function not calling a switch structure properly

so here in my code no matter how much i change i cant get it to work properly
it is supposed to go to question. that includes scanning for a int which corresponds to an option
then its supposed to call navigate now with the option declared and work with it
but no matter what option you choose it just says
sorry
#include <stdio.h>
#include <stdlib.h>
#define OPENWINDOW "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
void question(int option)
{
printf("What Would You Like To Do?\n");
printf("\t1.Add A Reminder\n\t2.View Reminders\n\t3.Manage Current Reminders\n\t4.Settings\n");
scanf("%i", &option);
}
void navigate(int option)
{
switch(option)
{
case 1:
printf(OPENWINDOW);
break;
case 2:
printf(OPENWINDOW);
break;
case 3:
printf(OPENWINDOW);
break;
case 4:
printf(OPENWINDOW);
break;
default :
printf("sorry");
question(option);
}
}
int main()
{
int option;
question(option);
navigate(option);
return 0;
}
Arguments are passed by value, not reference. So, your "option" arg is going to "disappear" soon after the function ends.
If you pass the "reference" to the var then you can use it to fill the caller variable. The following code and example fixes it.
void question(int *option)
{
printf("What Would You Like To Do?\n");
printf("\t1.Add A Reminder\n\t2.View Reminders\n\t3.Manage Current Reminders\n\t4.Settings\n");
scanf("%i", option);
}
Then you call it like this:
int option;
question(&option);
// now you can use option...
Since function can return values, you could also:
int question(void)
{
int option;
printf("What Would You Like To Do?\n");
printf("\t1.Add A Reminder\n\t2.View Reminders\n\t3.Manage Current Reminders\n\t4.Settings\n");
scanf("%i", &option);
return option;
}
// ...
int option = question();
// ...
The navigate and main using reference (pointers):
void navigate(int *option)
{
switch(*option)
{
case 1:
printf(OPENWINDOW);
break;
case 2:
printf(OPENWINDOW);
break;
case 3:
printf(OPENWINDOW);
break;
case 4:
printf(OPENWINDOW);
break;
default:
printf("sorry");
question(option);
}
}
int main(void)
{
int option;
question(&option);
navigate(&option);
return 0;
}
You need to pass option as pass-by-reference. Pass the address of option to question() and update there.
Refer the modified code.
void question(int *option)
{
printf("What Would You Like To Do?\n");
printf("\t1.Add A Reminder\n\t2.View Reminders\n\t3.Manage Current Reminders\n\t4.Settings\n");
scanf("%i", option);
}
call the question() as,
question(&option);
You need to either pass pointer of option to question or return it from the function question.
In your case value of option in main() is not changing when you read it in question(). Update your code as
int question()
{
int option;
printf("What Would You Like To Do?\n");
printf("\t1.Add A Reminder\n\t2.View Reminders\n\t3.Manage Current Reminders\n\t4.Settings\n");
scanf("%i", &option);
return option;
}
int main()
{
int option;
option = question(option);
navigate(option);
return 0;
}
You are passing "option" as call by value. Hence whatever you pass to question(). Would be lost.
Either, you return "option" from question() and pass this to navigate().
#include <stdio.h>
#include <stdlib.h>
#define OPENWINDOW "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
int question()
{ int option;
printf("What Would You Like To Do?\n");
printf("\t1.Add A Reminder\n\t2.View Reminders\n\t3.Manage Current Reminders\n\t4.Settings\n");
scanf("%i", &option);
return option;
}
void navigate(int option)
{
switch(option)
{
case 1:
printf(OPENWINDOW);
break;
case 2:
printf(OPENWINDOW);
break;
case 3:
printf(OPENWINDOW);
break;
case 4:
printf(OPENWINDOW);
break;
default :
printf("sorry");
question(option);
}
}
int main()
{
int option;
option = question();
navigate(option);
return 0;
}
~
If you do not want to use pass-by-reference, you can use pass-by-value which you are using in your code. It only needs to be implemented properly. You can change your "void question" to return a value by changing the void to "int" and issuing a return statement before the end of question function. Check code below:
#include <stdio.h>
#include <stdlib.h>
#define OPENWINDOW "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"
int question()
{
printf("What Would You Like To Do?\n");
printf("\t1.Add A Reminder\n\t2.View Reminders\n\t3.Manage Current Reminders\n\t4.Settings\n");
scanf("%i", &option);
return i;
}
void navigate(int option)
{
switch(option)
{
case 1:
printf(OPENWINDOW);
break;
case 2:
printf(OPENWINDOW);
break;
case 3:
printf(OPENWINDOW);
break;
case 4:
printf(OPENWINDOW);
break;
default :
printf("sorry");
question(option);
}
}
int main()
{
int option;
option = question(option);
navigate(option);
return 0;
}
You are passing the variable option by value question(option)
You should pass option varible by reference
void question(int *option)
{
printf("What Would You Like To Do?\n");
printf("\t1.Add A Reminder\n\t2.View Reminders\n\t3.Manage Current Reminders\n\t4.Settings\n");
scanf("%i", option);
}
void navigate(int *option)
{
switch(*option)
{
case 1:
printf(OPENWINDOW);
break;
case 2:
printf(OPENWINDOW);
break;
case 3:
printf(OPENWINDOW);
break;
case 4:
printf(OPENWINDOW);
break;
default :
printf("sorry");
question(option);
}
int main()
{
int option;
question(&option);
navigate(&option);
return 0;
}
For more information regarding this have a look at this link Difference between call by reference and call by value
Because the variable option only pass its value into function question(), the variable option's value indeed is unchanged, so, maybe you should return the value of option in the function question()

Reading a text file to a doubly linked list

I'm coding a contact manager using a doubly linked list that is manipulated by functions using pointers that reads in a contactList.txt.
#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<process.h>
#include<stdlib.h>
#include<dos.h>
//functions
listelement * getFirst(listelement *listpointer,string query[MAX]);
void getLast();
void getEmail();
void getCompany();
void getNumber();
void editCon();
void delCon();
void addCon();
void listAll();
void sortCon();
void Menu (int *choice);
#define MAX 20
//struct to order contactList
struct contact
{
string firstName[MAX],lastName[MAX],email[MAX],companyName[MAX];
long phoneNum[MAX];
struct listelement *link
struct contact *next;
struct contact *prev;
}list;
int main()
{
listelement listmember, *listpointer;
string query;int iChoice = 0;
listpointer = NULL;
Menu (&iChoice);
int iChoice;
fflush(stdin);
scanf_s("%d", &iChoice);
// user enters one of 9 values
// options are as follows: get first name,last name,list all contacts,search through contacts,add a new contact,edit/delete or sort contacts.
switch(iChoice)
{
case 1:
{
printf ("Enter contact first name to get details ");
scanf ("%d", &query);
listpointer = getFirst (listpointer, query);
break;
}
case 2:
{
getLast();
break;
}
case 3:
{
listAll();
break;
}
case 4:
{
getEmail();
break;
}
case 5:
{
getCompany();
break;
}
case 6:
{
getNumber();
break;
}
case 7:
{
addCon();
break;
}
case 8:
{
editCon();
break;
}
case 9:
{
delCon();
break;
}
case 10:
{
sortCon();
break;
}
case 11: // exit
{
printf("\n\nProgram exiting!...");
exit(0);//terminates program
break;
}
default:
printf ("Invalid menu choice - try again\n");
break;
}//end of switch
return(iChoice);
}//end of main
//menu function to test if invalid input was entered in a menu choice.
void Menu (int *iChoice)
{
char local;
system("cls");
printf("\n\n\t\\n\n");
printf("\n\n\t\tWelcome to my Contact Manager\n\n");
printf("\n\t\t1. First name");
printf("\n\t\t2. Last name");
printf("\n\t\t3. List all contacts");
printf("\n\t\t4. Search email");
printf("\n\t\t5. Search company name");
printf("\n\t\t6. Search number");
printf("\n\t\t7. Add contact");
printf("\n\t\t8. Edit contact");
printf("\n\t\t9. Delete contact");
printf("\n\t\t10. Sort contacts");
printf("\n\t\t11. Exit");
printf("\n\n\t\tEnter your menu choice: ");
do
{
local = getchar ();
if ( (isdigit(local) == FALSE) && (local != '\n') )
{
printf ("\nYou must enter an integer.\n");
printf ("");
}
} while (isdigit ((unsigned char) local) == FALSE);
*iChoice = (int) local - '0';
}
//function to get a contact by entering first name
listelement * getFirst (listelement *listpointer, string query)
{
//variables
char query[MAX],firstName[MAX];
FILE *fp, *ft;
int i,n,ch,l,found;
system("cls");
do
{
found=0;
l=strlen(query);
fp=fopen("ContactList.txt","r");
system("cls");
printf("\n\n..::Search result for '%s' \n===================================================\n",query);
while(fread(&list,sizeof(list),1,fp)==1)
{
for(i=0;i<=l;i++)
firstName[i]=list.firstName[i];
firstName[l]='\0';
if(stricmp(firstName,query)==0)
{
printf("\n..::First Name\t: %s\n..::Second Name\t: %ld\n..::Email\t: %s\n..::CompanyName\t: %s\n..::Number\t: %s\n",list.firstName,list.lastName,list.email,list.companyName.list.phoneNumber);
found++;
if (found%4==0)
{
printf("..::Press any key to continue...");
getch();
}
}
}
if(found==0)
printf("\n..::No match found!");
else
printf("\n..::%d match(s) found!",found);
fclose(fp);
printf("\n ..::Try again?\n\n\t[1] Yes\t\t[11] No\n\t");
scanf("%d",&ch);
}while(ch==1);
}
Anyone have any idea as to where I'm going wrong in the code?Thanks
Your errors are because:
1) you don't define listelement anywhere
2) you don't define string anywhere (and it's not a type in C)
3) You need to move the #define MAX up above before you use it.
4) You don't define FALSE anywhere (and it's not a type in C)
5) You're redefining elements too, in getFirst() you've passed in query as a "string", then you
define a new query as a char array
6) You get redefinition errors because you've got more than one define. That's somewhat #5 but there's more as well. In your main you declare iChoice here: string query;int iChoice = 0;
then you declare it again int iChoice; right after your Menu() call
7) Please don't do fflush(stdin) that's undefined behavior as per the C standard

Resources