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()
Related
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");
}
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");
}
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.
So I'm writing a code for a program with multiple menus that write different struct datas to a file and then with another menu that displays the data written in those files. Here's the code for the menu:
void displayall()
{
FILE *fp;
int choice=0;
struct depart loc = {0};
struct arrive loc1 = {0};
struct travel trav = {0};
fp=fopen("traveldat.dat","r");
while (1)
{
fread(&loc,sizeof(loc),1,fp);
fread(&loc1,sizeof(loc1),1,fp);
fread(&trav,sizeof(trav),1,fp);
double distance,time;
distance = sqrt(pow((loc1.x2-loc.x1),2)+pow((loc1.y2-loc.y1),2));
time = distance/trav.spd;
if (feof(fp))
{
break;
}
printf("\tYour departure location is : %s\n",loc.dep);
printf("\tWith the x-coordinate : %.2f\n",loc.x1);
printf("\tAnd the y-coordinate : %.2f\n\n",loc.y1);
printf("\tYour destination location is : %s\n",loc1.dest);
printf("\tWith the x-coordinate : %.2f\n",loc1.x2);
printf("\tAnd the y-coordinate : %.2f\n\n",loc1.y2);
printf("\tThe distance between these two locations is : %.2fkm\n\n",distance);
printf("\tYour preferred travel method is : %s\n",trav.mthd);
printf("\tWhich has a top speed of : %.2f km/h\n\n",trav.spd);
printf("\tYour expected travel time is : %.2f hours*\n\n",time);
printf("\t*Estimation,actual travel times may vary depending on certain conditions\n\n");
printf("\tThe system will now display the Main Menu\n\n");
}
fclose(fp);
}
The problem I'm facing is that if I go to the menu that writes loc1 or trav before the menu that writes loc, the display menu doesn't work, returns to the main menu, and then refuses to open whenver I try to access it. Is it because fread(&loc) is placed before the other freads? Or is there something I'm missing? Apologies in advance if this code is an eyesore or if I'm asking wrongly, I've only been learning programming for about a month.
Edit: loc1 and loc code as requested
void arrival_location_menu()
{
FILE *fp;
int choice=0;
struct arrive loc1;
fp=fopen("traveldat.dat","a");
printf("Please select your option (Destination location)\n");
printf("1.HOME\n");
printf("2.Andromeda Galaxy\n");
printf("3.The Library\n");
printf("4.Cprogramming.com\n");
printf("5.Return to main menu\n");
scanf("%d",&choice);
fflush (stdin);
switch (choice)
{
case 1: loc1.x2 = 3750;
loc1.y2 = 3450;
loc1.dest = "HOME";
system("CLS");
break;
case 2: loc1.x2 = 9870;
loc1.y2 = 5660;
loc1.dest = "Andromeda Galaxy";
system("CLS");
break;
case 3: loc1.x2 = 1367;
loc1.y2 = 3123;
loc1.dest = "The Library";
system("CLS");
break;
case 4: loc1.x2 = 2133;
loc1.y2 = 4767;
loc1.dest = "stackoverflow.com";
system("CLS");
break;
case 5: system("CLS");
break;
default: printf("Invalid option! Returning you to main menu...\n");
}
fwrite(&loc1,sizeof(loc1),1,fp);
fclose(fp);
return;
}
//DEPARTURE MENU
void departure_location_menu()
{
FILE *fp;
int choice=0;
struct depart loc;
fp=fopen("traveldat.dat","w");
printf("Please select your option (Departure location)\n");
printf("1.UTAR\n");
printf("2.PLUTO\n");
printf("3.IDK\n");
printf("4.UMM\n");
printf("5.Return to main menu\n");
scanf("%d",&choice);
fflush (stdin);
switch (choice)
{
case 1: loc.x1 = 1738;
loc.y1 = 1997;
loc.dep = "UTAR";
system("CLS");
break;
case 2: loc.x1 = 9850;
loc.y1 = 5675;
loc.dep = "PLUTO";
system("CLS");
break;
case 3: loc.x1 = 1363;
loc.y1 = 3125;
loc.dep = "IDK";
system("CLS");
break;
case 4: loc.x1 = 2130;
loc.y1 = 4785;
loc.dep = "UMM";
system("CLS");
break;
case 5:
system("CLS");
break;
default: printf("Invalied option!\n");
}
fwrite(&loc,sizeof(loc),1,fp);
fclose(fp);
return;
}
You seem to be asking if you can read data from anywhere in the file. Yes you can.
There is a function called fseek() to adjust the file pointer. The file pointer is the location next read from or written too.
There is also a function called ftell() to read the current file pointer. That's important if you're going to change the file pointer and want to restore it later.
I would also suggest you get into the habit of initializing variables ( even if it's to NULL or zero ), and of checking return values from functions. These two simple things can make debugging so much simpler.
I believe user #m-m has already explained the coding logic error.
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