C Program not going inside loop for Guess the number - c

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.

Related

Getting weird output in c with structures

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.

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.

why this program gives a "segmentation fault" when run on my linux?

Write a program for a match stick game being played between the computer and a user.Your program should ensure that the computer should ensure that the computer always wins.Rules for the game are as follows:
-There are 21 matchsticks.
-The computer asks the player to pick 1,2,3 or 4 matchsticks.
-After the person picks,the computer does its picking.
-Whoever is forced to pick up the last matchstick loses the game.
#include<stdio.h>
main()
{
int n,rem;
printf("Initially 21 mathces\n");
rem=21;
for(;1;)
{
if(rem==1){
printf("Com wins\n");
break;
}
else if(rem==0){
printf("Player wins\n");
break;
}
else{
printf("Player's turn.Enter number:");
scanf("%d",n);
rem=rem-n;
}
printf("remaining sticks=%d",n);
if(rem==1){
printf("Player wins");
break;
}
else if(rem==0){
printf("Com wins");
break;
}
else{
if(rem>6){
if((rem-6)<=4){
n=rem-6;
}
if((rem-6)>4){
n=4;
}
}
if(rem==6) n=1;
if(rem<6){
n=rem-1;
}
printf("Com chooses: %d",n);
}
printf("Remaining sticks=%d",rem);
}
}
scanf function expects address of the variable, you have passed the (value of) variable itself.
scanf("%d",n);
Use this way:
scanf("%d",&n); // '&' is 'address of' operator and evaluates to address of the variable
You are getting Seg Fault because scanf treats n as address of some variable, however n contains some garbage value, and may be that garbage value is some inaccessible/disallowed address in memory, therefore you get Seg Fault.
It is an undefined behavior, may be tomorrow you restart your system and do not get Seg Fault, but anyways your code will not work the way you want it to.

In C, How can I evaluate a local variable thats in one function, in a different function?

Ok so I'm creating this text adventure game. To be all unique and different, I decided to add an influence system where your responses to other characters can affect their responses to you as well their combat effectiveness.
I have a fair amount of experience in C++ and I just started my second semester-long course in C. So far, I have tried using global variables, structs, static variables, and using functions inside of other functions. I also tried using pointers but I kept getting errors every time so I stopped. This is a snippet of code that tries to use the influence system(Sorry for the stars, wouldn't want to give away any story plots):
#include <stdlib.h>
#include <stdio.h>
static int positive_Influence; int negative_Influence; int overall_Influence;
void printpInI(int positive_Influence, int negative_Influence);//positive and negative influence
int choice_6()
{
int choice = 0;
int positive_Influence, negative_Influence, overall_Influence;
positive_Influence = 0;
negative_Influence = 0;
overall_Influence = 0;
printf("What do you do?\n");
printf("\t1. You: ****\n");
printf("\t2. You: ****\n");
printf("\t3. You: ****\n");
do
{
scanf_s("%i", &choice);
switch (choice)
{
case 1:
{
printf("\t****?\n");
system("pause");
negative_Influence += 10;
printf("You lose influence and are now at %i with ****.\n", positive_Influence-negative_Influence);
break;
}
case 2:
{
printf("\t****");
system("pause");
positive_Influence += 10;
printf("You gain influence and are now at %i influence with ****.\n", positive_Influence-negative_Influence);
break;
}
case 3:
{
printf("**** smiles at this.\n");
system("pause");
positive_Influence += 10;
printf("You gain influence and are now at %i influence with ****.\n", positive_Influence-negative_Influence);
break;
}
}
}while(choice != 1 && choice != 2 && choice != 3);
overall_Influence = positive_Influence-negative_Influence;
printf("%i\n", overall_Influence);
}
void story_7()
{
printf("Your overall influence is %i\n", overall_Influence);
}
int main()
{
choice_6();
story_7();
system("pause");
}
You have declared overall_influence as a global but also as a local in choice_6. The local declaration takes precedence; just remove that and you should be OK. Same thing about the variables positive_influence and negative_influence.
Can you tell me which type of errors you got? Also you already declared global variables for calculating influence so why you again declared it locally in choice_6 function and that is the error case in you program so local variables have more precedence then global one within function in which they declared. So remove declaration from function choice_6.
I actually was just being really dumb because I forgot hows pointers worked (dam ampersans!) anyway thank you all for replying I really really do appreciate it. I am also working on a combat system that can use multiple enemies so keep watching my profile because I'll probably have moar questions later. If you would like to beta test, my email is mikemanahan15#gmail.com if you would like to play what I have so far. Of course, here is the finished code (for choice_6 and story_7) enjoy:
#include <stdlib.h>
#include <stdio.h>
int choice_6(int *influence)
{
int choice = 0;
printf("What do you do?\n");
printf("\t1. You: No. I know absolutely nothing about you. You could be a monster\n");
printf("\ttoo for all I know! Normal people don't turn into frogs!\n");
printf("\t2. You: Your right we should keep moving. You can tell me when your\n");
printf("\tready.\n");
printf("\t3. You: Okay where do you think should we go then?\n");
do
{
scanf_s("%i", &choice);
switch (choice)
{
case 1:
{
printf("\tBrie flashes a pained look on her face and you immediately regret saying that.\n");
printf("\tBrie: You really think I'm a monster?\n");
system("pause");
*influence -= 10;
printf("You lose influence and are now at %i with Brie.\n", *influence);
system("pause");
printf("Influence affects characters reactions towards you, their combat effectiveness, and even their allegiances in rare cases.\n");
printf("However, depending on the situation, low influence is not always a bad thing...\n");
system("pause");
printf("\tYou: Your right we should keep moving.\n");
break;
}
case 2:
{
printf("\tBrie: Thank you. I'd rather not discuss this my life story in a dark\n");
printf("\tdungeon.\n");
system("pause");
*influence += 10;
printf("You gain influence and are now at %i influence with Brie.\n", *influence);
system("pause");
printf("Influence affects characters reactions towards you, their combat effectiveness, and even their allegiances in rare cases.\n");
printf("However, depending on the situation, low influence is not always a bad thing...\n");
system("pause");
printf("\tYou: I'd have to agree with you there. Let's see what is up these stairs.\n");
choice = 2;
break;
}
case 3:
{
printf("Brie smiles at this.\n");
printf("\tBrie: Well the only way out seems to be these stairs so let's go up.\n");
system("pause");
*influence += 10;
printf("You gain influence and are now at %i influence with Brie.\n", *influence);
system("pause");
printf("Influence affects characters reactions towards you, their effectiveness in combat, and even their allegiances in rare cases.\n");
printf("However, depending on the situation, low influence is not always a bad thing...\n");
system("pause");
printf("\tYou: Sounds good to me I am quite frankly done with dungeons about now.\n");
break;
}
default:
{
printf("Type the number for the choice you want to do\n");
system("pause");
break;
}
}
}while(choice != 1 && choice != 2 && choice != 3);
}
int story_7(int influence)
{
if (influence > 0)
{
printf("Brie laughs at this and slowly leans you off her to have both of you crouch.");
system("pause");
}
else
{
printf("Brie: Ugh just get off of me!\n");
printf("Brie pushes you off her violently and you manage to stay crouched.");
system("pause");
}
}
int main()
{
int influence = 0;
// ...
choice_6(&influence);
story_7(influence);
// ...
}
You should remove the local variables and use scope resolution operator to use your global variables
This would solve your question.
Also you can use these variables in any function you want later.

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