Getting weird output in c with structures - c

I'm new to C programming and just doing homework, thing is, I cant figure out why this the choice "Visualizar platos del dia" outputs weird symbols and not the things that I've input in with the cargar structure.
#include <stdio.h>
#include <string.h>
#include <strings.h>
struct platos{
char aperitivo[40];
char plato1[40];
char plato2[40];
char postre[40];
char bebida1[40];
char bebida2[40];
char bebida3[40];
};
void cargar(struct platos a);
void vis(struct platos a);
void emit(struct platos a);
int main(){
int a=0, b=0;
struct platos plato;
do{
printf("Bienvenido a restaurante 'Senior bigotes'\n\n");
printf("1:Cargar platos del dia\n");
printf("2:VIsualizar platos del dia\n");
printf("3:Emitir comanda y factura\n");
printf("4:Salir\n");
scanf("%d", &a);
switch(a){
case 1: cargar(plato);
break;
case 2: vis(plato);
break;
case 3: emit(plato);
break;
case 4:
b++;
break;
}
}while(b<1);
return 0;
}
void cargar(struct platos a){
printf("Ingrese aperitivo\n");
__fpurge(stdin);
gets(a.aperitivo);
printf("Ingrese plato 1\n");
__fpurge(stdin);
gets(a.plato1);
printf("Ingrese plato 2\n");
__fpurge(stdin);
gets(a.plato2);
printf("Ingrese postre\n");
__fpurge(stdin);
gets(a.postre);
printf("Ingrese bebida 1\n");
__fpurge(stdin);
gets(a.bebida1);
printf("Ingrese bebida 2\n");
__fpurge(stdin);
gets(a.bebida2);
printf("Ingrese bebida 2\n");
__fpurge(stdin);
gets(a.bebida3);
}
void vis(struct platos a){
printf("\nAperitivo: %s", a.aperitivo);
printf("\nPlato 1: %s", a.plato1);
printf("\nPlato 2: %s", a.plato2);
printf("\nPostre: %s", a.postre);
printf("\nBebidas: %s | %s | %s\n", a.bebida1, a.bebida2, a.bebida3);
int c = getchar();
}
void emit(struct platos a){
printf("\nAperitivo: %s $10", a.aperitivo);
printf("\nPlato 1: %s $25", a.plato1);
printf("\nPlato 2: %s $35", a.plato2);
printf("\nPostre: %s $20", a.postre);
printf("\nBebidas: %s | %s | %s $15\n", a.bebida1, a.bebida2, a.bebida3);
printf("Total: $105");
int c = getchar();
}
I'm using manjaro btw with visual code. I asked the teacher and he wants me to debug the code but Idk how to do that in visual code. Any help?

If you mean Visual Studio Code, it has a Run menu item that contains the the debugging items, such as Toggle Breakpoint and Start Debugging.
The first can be used on the statement you want to start debugging with, and the second to start running your code. Once the breakpoint is hit, there should be a small panel on the screen somewhere with controls for continue, step over, step into, and so on:
If you hover over those controls, it should also show you the equivalent keyboard commands you can use.
However, you should be aware that, for your immediate problem, structures are passed by value in C, not by reference. That means that the cargar function gets a copy of plato and populates the fields of that copy.
Then that copy is thrown away when returning from cargar, leaving the original plato with the arbitrary field it was given at creation time. So, when that is subsequently passed to vis or emit, you won't see the data you entered.
The easiest solution is probably to pass a pointer (&plato) to cargar, and use -> rather than . to access the fields within that function. In other words, something like (see notes below as to why I'm using fgets()):
switch (a) {
case 1: cargar(&plato); break;
and
void cargar(struct platos const *a_ptr){
printf("Ingrese aperitivo\n");
__fpurge(stdin);
fgets(a_ptr->aperitivo, sizeof(a_ptr->aperitivo), stdin);
// And so on for the other fields ...
That particular const before *a_ptr applies to the pointer value itself rather than the value "behind" the pointer. You need to be able to change the value since that's the whole purpose of the function.
However, I'd also do something similar for vis() and emit() so as to not be copying large structures around but I'd use (for example):
void vis(const struct platos const *plato) {
to make it clear neither the pointer nor the value behind the pointer is expected to change.
And, as others have mentioned in comments, you should use fgets() rather than gets(), there is no way to use the latter safely. If you want to know how to use it for user input, see this answer.
It should be an indication of how bad gets() is considered that it's actually been deprecated and removed from the standard.

Related

What memory is my program trying to access? because its seg faulting

**I have traced through the code 3 times but I still cant figure out the cause of the seg fault, I am trying to get a menu printed by opening files and displaying the contents in organized form, it so frustrating, I am already confused by my code and even more so by seg fault, any help would be highly appreciated, I know this will turn into a code review
​
typedef struct{
char item[30];
char quantity[20];
int calories;
float protein;
float carbs;
float fats;
} food;
typedef struct {
char month[4];
int day, year;
} date;
int foodCount; // counter variable to keep track of the number of foods that are chosen
void initializeArray(FILE *dataFile, int arraySize, food foodType[]) // arrayProcessing.c
{
int i;
// struct food foodType[arraySize];
for(i=0;i<arraySize;i++)
{
scanf("%s",foodType[i].item);
scanf("%s",foodType[i].quantity);
scanf("%d",&foodType[i].calories);
scanf("%f",&foodType[i].protein);
scanf("%f",&foodType[i].carbs);
scanf("%f",&foodType[i].fats);
}
}
// used for the food arrays as well as the chosen foods
void printArray(int arraySize, food foodType[]) // arrayProcessing.c
{
int n;
printf("FOOD ITEM%25s%9s%10s%8s%8s\n","QUANTITY","CALS","PRO","CARBS","FAT");
for(n=0;n<arraySize;n++){
printf("%d. %-20s\t%10s\t%3d\t%5.2f\t%5.2f\t%5.2f\n",n+1,foodType[n].item,foodType[n].quantity,
foodType[n].calories, foodType[n].protein, foodType[n].carbs, foodType[n].fats);
}
}
int printMainMenu() // menu.c
{
int choice;
printf("\n MAIN MENU");
printf("\n 1. choose lean protein");
printf("\n 2. choose fruit");
printf("\n 3. choose complex carbs (starches & grains)");
printf("\n 4. choose fibrous carbs (veggies & greens)");
printf("\n 5. choose dairy");
printf("\n 6. choose fats, oils, nuts, seeds");
printf("\n 7. show totals");
printf("\n 8. quit program");
scanf("%d", &choice);
return choice;
int main (){
int arraySize, choice;
FILE *dataFile;
food foodType[arraySize];
do
{
choice=printMainMenu();
switch(choice)
{
case 1: {
dataFile=fopen("leanProteins.txt","r");
fscanf(dataFile,"%d",&arraySize);
initializeArray(dataFile, arraySize, foodType);
printArray(arraySize, foodType);
break;
}
case 2:{
dataFile=fopen("fruit.txt","r");
fscanf(dataFile,"%d",&arraySize);
initializeArray(dataFile,arraySize, foodType);
printArray(arraySize, foodType);
break;
}
case 3:{
dataFile=fopen("complexCarbs.txt","r");
fscanf(dataFile,"%d",&arraySize);
initializeArray(dataFile,arraySize,foodType);
printArray(arraySize, foodType);
break;
}
case 4:{
dataFile=fopen("fibrousCarbs.txt","r");
fscanf(dataFile,"%d",&arraySize);
initializeArray(dataFile,arraySize,foodType);
printArray(arraySize, foodType);
break;
}
case 5:{
dataFile=fopen("dairy.txt","r");
fscanf(dataFile,"%d",&arraySize);
initializeArray(dataFile, arraySize, foodType);
printArray(arraySize,foodType);
break;
}
case 6:{
dataFile=fopen("fats.txt","r");
fscanf(dataFile,"%d",&arraySize);
initializeArray(dataFile, arraySize, foodType);
printArray(arraySize,foodType);
break;
}
case 7:{
printf("show totals");
break;
}
case 8:{
exit(0);
}
default:
printf("invalid selection!");
}
}while(choice!=8);
return 0;
}
Hint only since this is almost certainly classwork, and you'll become a much better developer if you learn to nut things out yourself :-)
int arraySize, choice;
FILE *dataFile;
food foodType[arraySize];
Here's a question you should ask with regard to the snippet above. What is the value of arraySize at the point where the foodType array is created?
A couple of other things to consider.
You're likely going to run out of file handles if you keep opening files and not closing them.
You appear to want to read food details from a file (which you open) but you never actually use the file handle. Instead, you scanf the information from standard input.
And, on that scanf (specifically with "%s"), you need to be absolutely certain that your data is correct. Crashing is frequently caused by reading in a string that's too long for the buffer you've provided.
Still with the scanf("%s"), you should be aware that it will stop on the first whitspace so, if your file contains the "Long grain Basmati" complex carb, all you're going to see is Long. And this will almost certainly complicate your input as you try to read the rest of the line as non-string data (like a calorie count of "rice", for example).
You should generally always check the return value of the scanf family to ensure it has scanned the number of items you expected.
Those last three points could probably be solved with a more robust input function, one which prevents buffer overflow and checks the data being read to ensure it's valid (like reading as a string first, checking the content as a string, then converting to integer or float).
I have such a beast here that works well for standard input, it reads the entire line safely. It wouldn't be hard to adapt this to use any file handle and then you could use sscanf to turn that into individual fields after checking.

Running C program returns -1.#QNAN0 instead of number stored in floating-point variable

Before going on, I'd like to say that this is my first time here and I don't know how things work yet so please pardon any errors on my part.
When compiled,(source code below) everything works fine except for the content of the float disp which is equal to -1.#QNAN0. Any help on this? Thanks in advance. Some parts of the code are not complete like the switch-case structure. Please temporarily that(Unless it affects the result).
The source code for the C program:
#include <stdio.h>
#include <stdlib.h>
float moneyup(float m);
int main()
{
char name[20];
char x;
int y;
float disp;
int hunger;
printf("\t\t**********************************************\n");
printf("\t\t* *\n");
printf("\t\t* How To Get Rich Quick! *\n");
printf("\t\t* *\n");
printf("\t\t**********************************************\n");
printf("\nThis is an experimental command line interface game made by NayNay AKA Nathan\n");
printf("\nPlease pardon the poor user interface.");
for(;;)
{
printf("\nPlease enter your name(one only)");
scanf("%s", &name);
printf("\nThe name you entered is %s. Is this correct? (type y/n for yes or no)\n");
fflush(stdin);
x=getchar();
if(x=='y') /*This part with the for loop is used to get the name of the*/
{ /*user and confirm the correctness of that name. If the name is*/
printf("Okay! Moving on..."); /*wrong, the user has the option to change it. Bulletproofing used*/
break; /*here*/
}
else if(x=='n')
{
printf("Alright let's try again.");
continue;
}
else
{
printf("Let's try this again.");
continue;
}
}
printf("\nOkay %s, Let's get this story started",name);
printf("\n\nOne sad dreary morning, %s got up from sleep and went to the kitchen to get breakfast.");
printf("\nUnfortunately for him his pantry only contained a bunch of cockroaches going at it and laying their eggs everywhere");
printf("\nHe then checked his pockets and pulled out his last 5-dollar bill. That was all he had left,");
printf("\nHe bought a sandwich for $2 and decides to start a business with $3 as capital");
printf("\n\nChoose how to start");
printf("\n1. Begging.");
printf("\n2. Mow lawns.");
printf("\n3. Apply for post of newspaper boy.");
fflush(stdin);
y=getchar();
switch(y)
{
case '1':
printf("You begged for 6 hours and got $5.25\n");
disp=moneyup(5.25);
printf("You now have $%f\n",disp);
}
return 0;
}
float moneyup(float m)
{
float money;
money=(float)money+m;
return(money);
}
The variable money is uninitialized in the function moneyup when used in expression
money=(float)money+m;

C Program not going inside loop for Guess the number

I have written the following code for the computer to guess what my number is, I have used switch case statement here which is inside a do while loop.
When I tried to run the program, the program doesnt go inside my loop, and I dont know how to fix it, can anyone help me out please?
#include<stdio.h>
void main()
{
printf("\n Grenze 1 - Obergrenze. ");
int min=1;
int max;
printf("\n Was ist Obergrenze? ");
scanf("%i",max);
int try=max;
int correct;
int input,i=0;
do{
correct=max/2;
printf("Low(1) High(2) oder Correct(3)? \n >");
start:
scanf("%i",input);
i++;
switch (input)
{
case(1):
{
min=min;
max=max/2;
} break;
case(2):
{
min=max/2;
max=max;
}break;
case(3):
{
goto gotcha;
}break;
default:
{
printf("\n >");
goto start;
}break;
}
}
while(i<try);
gotcha:
printf("\n Wieder gewonnen!!! Versuche - %i",i);
}
You are invoking undefined behavior by passing what is not a pointer and using value of uninitialized variable having automatic storage duration, which is indeterminate, inscanf("%i",max);.
The same problem is in scanf("%i",input);.
Use unary & operator to pass the address to read data into likescanf("%i",&max); and scanf("%i",&input);.
Also note that you should use standard int main(void) in hosted environment instead of void main(), which is illegal in C89 and implementation-defined in C99 or later, unless you have some special reason to use non-standard signature.

function prototype in c, compile error

So am trying to learn c by-myself (basically not having any previous experience in any programming language) and now I have some issues with prototyping some of my functions to use in header files.
For the sake of learning I only use the < stdio.h > lib and only use the printf and scanf functions and for now it only prints to console.
I was able to code a working prototype function for my menu that only uses the printf function but the scanf gives me more issues and it just refuses to compile and am having trouble to see where my thinking error is.
my main program:
#include "menu.h"
#include "circlefunctions.h"
#include "input.h"
int main(void){
float diameter;
double straal;
double oppervlakte;
double omtrek;
while(1){
menu();
user_input();
system("cls");
switch(user_input())
{
case 1:
printf(" ----------------------------------------\n");
printf(" Typ de diameter van de cirkel: ");
scanf("%g", &diameter);
printf(" ----------------------------------------\n");
straal = diameter / 2;
oppervlakte = PI * (straal * straal);
omtrek = 2 * PI * straal;
printf(" De straal = %f \n\n", straal );
printf(" De oppervlakte = %f \n\n" , oppervlakte);
printf(" De omtrek = %f \n" , omtrek);
printf(" ----------------------------------------\n");
break;
case 2:
return(0);
case 3:
return(0);
case 9:
return(0);
case 0:
return(0);
}
}
return 0;
}
and the stubborn header:
#include <stdio.h>
void user_input();
void user_input(){
scanf("%d", &user_input);
}
The error that I get while trying to compile is in input.h
the part with; scanf("%d", &user_input);
errorcode: format '%d' expects argument type of 'int ', but argument 2 has type 'void () ()'.
And I also got an error on the switch in the main program that the switch quantity is not an integer. I suspect that this error is related but am not sure. I still have to debug that part but if anyone is willing to point me to the right documentation i would much appreciate it.
And a second question that I have is also related to headers: I have < stdio.h > already included in "menu.h". Would I need to include it again in "input.h"?
(if i understand correctly how the preprocessor works i should not have to include it but I can't find anywhere where this is explained in simple terms unfortunately.)
Edit:
Thank you all for providing valuable information.
#zenith Thank you for your example. I hope you don't mind me asking some more.
I have replaced my code with yours in the "input.h" and it will compile and run now. However the behavior has changed. For some unclear reason i now have to input the choice twice before the program accepts my input. So the 1st input gets ignored after an enter and it will only accept the 2nd input.
Could you perhaps point me in the direction what causes this bug? or perhaps point me to some documentation where this is explained? I don't want to take up to much of you valuable time of-course.
Edit 2
Thanks for the reply and info. I got the bug out and it is working as intended(that was silly of me not to see that).
And to the rest who replied: Ill take your information of-course and also learn from that. Thank you all!
user_input() doesn't return anything, since it's declared void.
But you're trying to use the non-existing return value: switch(user_input()).
This causes undefined behavior.
Additionally, this:
scanf("%d", &user_input);
tries to read an int from stdin and store it in the memory address of the user_input function. Not a good idea. Again, undefined behavior.
What you probably want the function to look like:
int user_input(){
int number; // store user input to this variable
scanf("%d", &number);
return number; // return the user input so that it can be used outside the function
}
If you have header files declared in a previous header file. You will not need to include it again in the subsequent included header files. I tend to not include header files in my local *.h files just for that reason. It avoids circular includes if you declare your includes in the .c files as much as possible.
Your scanf function has as its second argument a function of type void(), void(). Meaning it takes no arguments and returns nothing or "void". I think you want your user_input to be a variable of type 'double' that is filled somewhere, maybe via some user input from the console using a call to 'gets' from stdin.
HTH

program running through my if else after function call

I have a class assignment in C to make a simple calculator that performs three calculations. I haven't completed all of the functions yet but I am having a problem with my calcMenu function. When the function is called the program runs through all of the if else statements and unknown to me, performs only the else statement which is error checking. Than the function is run again which is intended but this time it does not run through all of the if else statements and allows the user to make a choice. I know I have done something really stupid but have been racking my brain for the last hour. If anyone has any pitty for me, than please point me in the right direction. I know all the system calls will Irk some but this is a basic class and our instructor has told us to use them.
Thanks in advance,
Mike
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#define pause system ("pause")
#define cls system ("cls")
//Prototype calculate functions here
void evenOrOdd(int userNumber);
void squareNum(int userNumber);
void cubeNum(int userNumber);
void calcMenu(int userNumber);
void main() {
//Declare local variables here
int userNumber = 0;
printf("\t\t\tThe amazing three function caluculator\n\n\n");
printf("Please enter a whole number that you would like to calculate\n");
scanf("%d", &userNumber);
calcMenu(userNumber);
}
void calcMenu(int userNumber)
{
char calculateOption;
printf("\nWhat calculation would you like to perform with your number?\n\n");
printf("Press A.) to check if your number is even or odd.\n\n");
printf("Press B.) to calculate the square of your number.\n\n");
printf("Press C.) to calculate the cube of your number.\n\n");
printf("press D.) to exit the program.\n");
scanf("%c", &calculateOption);
calculateOption = toupper (calculateOption);
if (calculateOption == 'A')
{
evenOrOdd(userNumber);
}
else if (calculateOption == 'B')
{
squareNum(userNumber);
}
else if (calculateOption == 'C')
{
cubeNum(userNumber);
}
else if (calculateOption == 'D')
{
system("cls");
printf("Thank You for using my amazing calculator.\n\n");
system ("pause");
system ("exit");
}
else
{
printf("Please enter a valid choice");
calcMenu(userNumber);
}
}
void evenOrOdd(int userNumber) {
userNumber = userNumber %2;
if (userNumber == 0)
{
printf("Your number is even. \n");
}
else
{
printf("Your number is odd. \n");
}
}
void squareNum(int userNumber) {
}
void cubeNum(int userNumber){
}
When you read input with scanf you have to press the Enter key to make the program continue. Your scanf call reads the single character from the input, but leaves the Enter key still in the input buffer, to be read next time you call scanf.
There is a very simple trick to solve that: Place a space in the scanf format string before or after the "%c". This will make scanf skip whitespace.
scanf("%c ", &calculateOption);
If you stepped through the code with a debugger you would have easily seen that calculateOption would have been the newline character.
First of all, You can condense all those printf statements into one function to save the extra calls.
Next, you should probably indent your functions, I can't tell where one begins and another ends at a glance.
Third, don't use system("pause"), use getchar().
Fourth, this is optional, you might want to turn those if statements into a switch statement.
Now, on to your question. First of all, instead of using scanf("%c", &calculateOption), just use getchar() here too. In this case, I would write calcMenu() as this:
int calcMenu(int userNumber){
printf("\nWhat calculation would you like to perform with your number?\n\n\
Press A.) to check if your number is even or odd.\n\n\
Press B.) to calculate the square of your number.\n\n\
Press C.) to calculate the cube of your number.\n\n\
Press D.) to exit the program.\n");
switch(toupper(getchar())){
case 'A':
evenOrOdd(userNumber);
break;
case 'B':
squareNum(userNumber);
break;
case 'C':
cubeNum(userNumber);
break;
case 'D':
system("cls"); //this is bad, really.
printf("Thank You for using my amazing calculator.\n\n");
getchar();
return 0;
default:
printf("Please enter a valid choice: ");
calcMenu(userNumber);
break;
}
}
Also, main should always return a value. void main is bad practice.
Disclaimer: The code isn't tested, you shouldn't copy/paste it anyways. I also don't know if you're being forced to use some things or not...

Resources