Finding Items in Struct and edit them - c

i have a problem in my code (Case 2), I try to get the position of the item what I get from the scanf() but when I try to get the position it give me a complete random number like 537890.
I can't figure out why my code do that, because the max size of my struct ist 200.
I'm not sure if its because I tried to do &find==wh[a]->artikel
int main() {
struct managementtool {
char artikel[200];
int anzahl;
};
//wh = warehouse
struct managementtool **wh = malloc(200 * sizeof(struct managementtool *));
for (int i = 0; i < 200; i++) {
wh[i] = malloc(sizeof(struct managementtool));
}
printf("Welcome to Warehouse Management 97\n\n\nWhat do you want to do ?\n");
int x,v,f,i,exit,all,end,a,b;
char ques,find, nu1;
do {
i=0;
printf("\n(1)Add article\n(2)Edit article.\n(3)Search entry.\n(4)Show stock.\n(5)Exit\n");
scanf("%x",&x);
switch (x) {
case 1://add
do {
printf("\nEnter the product name: ");
scanf("%s", wh[f]->artikel);
printf("\nAmount of products: ");
scanf("%i", &wh[f]->anzahl);
printf("\n\nAdd another product ? (Y/N)");
// add a space before % to skip leading whitespace
scanf(" %c", &ques);
f++;
switch (ques) {
case 'Y':
v++;
break;
case 'N':
end = 1;
v = 0;
break;
default:
printf("Wrong entry\n");
break;
}
} while (end != 1);
if (v >= 2) {
printf("Product added successfully\n\n");
}else {
printf("Products have been successfully added\n\n");
}
break;
case 2://edit
printf("Which article do you want to edit?");
fflush(stdin);
scanf("%s", &find);
for (a=0;a<f;a++) {
if (&find==wh[a]->artikel) {
b=a;
}
}
if (b==0) {
printf("Article not found");
}
printf("f: %i, b:%i",f,b);
puts(wh[b]->artikel);
printf("Amount: %d\n", wh[b]->anzahl);
break;
case 3://search
break;
case 4://Spam-it
while (i<f) {
printf("\nProduct number %i\n", i+1);
printf("Name: ");
puts(wh[i]->artikel);
printf("Amount: %d\n", wh[i]->anzahl);
i++;
}
printf("\nTotal amount of Items: %i", all);
break;
case 5://go away
printf("Goodbye :)");
exit=1;
break;
default://well
printf("Wrong Input\n");
break;
}
all=0;
while (i<f) {
all += wh[i]->anzahl;
i++;
}
} while (exit==0);
}

In C you need to use strcmp instead of using == to compare strings. You should also use fgets instead of scanf it will make your life easier, you don't have to worry about trying to flush. Example : fgets( my_string_buffer, number_of_char_maximum_to_read , stdin ) . Example for strcmp : if(! strcmp( string1 , string2) , strcmp returns 0 if they are identical.

Related

using the function findMovie for the second time, visual studio throws exception

visual studio throws an exception to the second instance of find movie under case c, it says it has not been initialized yet although in the local windows it shows the struct with info inside?Run-Time Check Failure #3 - The variable 'tempMovie' is being used without being initialized. this only happens the second time i try to use the struct tempMovie
#include <stdio.h>
#include <conio.h>
#include <string.h>
#define CONST 100
typedef struct movies {
char title[30];
char UPC[12];
int qnty;
double price;
}movies;
void sortMovies(struct movies main[], int nOfMovies);
void changeMovie(struct movies main);
int findMovie(struct movies main, int nOfMovies, struct movies tempMovie);
struct movies newMovie();
int main()
{
int nOfMovies = 0, findR, stop = 0, nOfMoviesArr[CONST];
char decider;
while (stop != 1)
{
movies main[CONST];
movies tempMovie;
printf("(A)dd a new movie\n(C)hange a Movie's Information \n(D)elete a Movie \n(L)ist All Movies\n(Q)uit\n\n");
scanf(" %c", &decider);
switch (decider)
{
case 'a':
case 'A':
tempMovie = newMovie();
findR = findMovie(main[nOfMovies], nOfMovies, tempMovie);
if (findR == -1)
{
nOfMovies += findR;
break;
}
else
main[nOfMovies] = tempMovie;
nOfMovies++;
break;
case 'c':
case 'C':
findR = findMovie(main[nOfMovies], nOfMovies, tempMovie);
changeMovie(main[findR]);
break;
case 'd':
case 'D':
break;
case 'l':
case 'L':
sortMovies(main, nOfMovies);
break;
case 'q':
case 'Q':
return 0;
break;
default:
printf("An invalid option was selected!");
}
}
}
struct movies newMovie() {
movies new;
printf("enter movie upc:");
scanf("%s", &new.UPC);
printf("enter movie title:");
scanf("%s", &new.title);
printf("enter movie qauntity:");
scanf("%d", &new.qnty);
if (new.qnty <= 0)
{
printf("quanitity must be greater than 0");
printf("enter movie qauntity:");
scanf("%d", &new.qnty);
}
printf("enter movie price:");
scanf("%lf", &new.price);
if (new.price <= 0)
{
printf("price must be greater than 0");
printf("enter movie price:");
scanf("%lf", &new.price);
}
return new;
}
int findMovie(struct movies main, int nOfMovies, struct movies tempMovie)
{
int count;
for (count = 0; count < nOfMovies; count++)
{
if (tempMovie.UPC != main.UPC)
{
return count;
}
else
{
printf("error");
return -1;
}
}
}
void changeMovie(struct movies main)
{
char decider;
printf("would you like to change the value? y or no input");
switch (decider)
{
case 'y':
case 'Y':
printf("enter movie title:");
scanf("%c", main.title);
printf("enter movie qauntity:");
scanf("%d", main.qnty);
if (main.qnty <= 0)
{
printf("quanitity must be greater than 0");
printf("enter movie qauntity:");
scanf("%d", main.qnty);
}
printf("enter movie price:");
scanf("%lf", main.price);
if (main.price <= 0)
{
printf("price must be greater than 0");
printf("enter movie price:");
scanf("%lf", main.price);
}
break;
default:
printf("An invalid option was selected!");
}
}
void sortMovies(struct movies main[], int nOfMovies)
{
int i, sflag, count = 0;
char* temp;
do
{
sflag = 0;
for (i = 1; i < nOfMovies; i++)
{
if (main[i - 1].title > main[i].title)
{
temp = main[i - 1].title;
strcpy(main[i - 1].title, main[i].title);
strcpy(main[i].title, temp);
sflag = 1;
}
}
count++;
} while (sflag);
for (i = 0; i < nOfMovies; i++)
{
printf("%s\t%s\t%d\t%.2lf\n", main[i].title, main[i].UPC, main[i].qnty, main[i].price);
}
}```
Error may be due to any or many the following reasons:
In changeMovie(), the variable decider is not scanned.
In scanf(), use a spaces omitted before "%c" and "%s" (Use " %c" and " %s")
In changeMovie(), syntax error while scanning (Use &main.qnty instead of main.qnty)
The function changeMovie() is changing the formal parameters and not altering the actual parameters
Also, there are a few logical errors. For instance, in the line if (new.price <= 0) a while should be used instead of an if

I cant seem to understand how to restrict my scanf to only numbers of float

#include <stdio.h>
#include <string.h>
#define mL 5
#define NL 20
#define UL 6
struct LIST
{
char n[NL];
float am;
char u[UL];
};
struct array
{
struct LIST array;
};
void addCityInformation(struct array *add, int *items);
void printCities(struct array *all, int items);
int main(void)
{
struct array shopping[mL];
int choice, nrOfItemsAdded = 0;
do
{
printf("\nWhat du you want to do?");
printf("\n1 - add grocery");
printf("\n2 - print shopping list");
printf("\n3 - exit");
printf("\nYour choice: ");
scanf("%d", &choice);
while(getchar() != '\n');
switch (choice)
{
case 1:
addCityInformation(&shopping[nrOfItemsAdded], &nrOfItemsAdded);
break;
case 2:
printCities(shopping, nrOfItemsAdded);
break;
case 3:
printf("Exiting program\n\n");
break;
default:
printf("Invalid input\n\n");
break;
}
}
while(choice != 3);
return 0;
}
int clean_stdin()
{
while (getchar()!='\n');
}
void addCityInformation(struct array *add, int *items)
{
if(*items == mL)
printf("No more space in the list\n");
else
{
printf("Enter name: ");
fgets(add->array.n, NL, stdin);
add->array.n[strlen(add->array.n)-1] = '\0';
do {
printf("Enter amount: ");
}while (scanf("%f", &add->array.am )); //loop untill other than float
getchar();
printf("Enter unit: ");
fgets((add->array.u), UL, stdin);
add->array.u[strlen(add->array.u)-1] = '\0';
(*items)++;
}
}
void printCities(struct array *all, int items)
{
printf("\n\n%-20s %-15s %-9s | %-6s\n", "Name", "amount", "unit");
printf("--------------------------------------------------------\n");
for(int i = 0; i < items; i++)
printf("%-20s %-15.1f %-9.4s \n", all[i].array.n, all[i].array.am, all[i].array.u);
}
This is my loop beside that i am only showing a part of the code. It now just continues to give enter amount and letting me register it in the struct. I want to restrict the user to only entering positive numbers and no character at all. And if he types a character it should rerun the loop even if it is 123Av123 it should run the loop and only register the correct number
Edit: now showing the whole code//loop untill other than float is what i want help with
int check=scanf("%f", &add->array.am )
if(check!=1||add->array.am<0){
printf("Incorrect input");
return 1;
}
I think that will do it.
Edit: you wanted it to rerun after so use continue; instead of return;

Should I include both fflush(stdin) and a space in scanf() or will only one of them suffice? [duplicate]

This question already has answers here:
Using fflush(stdin)
(7 answers)
Closed 4 years ago.
My calculator app hasn't been working properly after a user inputs a number. So I added fflush(stdin) and a space after the %d in scanf(). My question is should I only include both fflush(stdin) and a space after %c or will only one of the options suffice? I'm working on a Macbook, so I'm concerned that if I leave one out it won't work on other operating systems.
#include <stdio.h>
#include <stdlib.h>
//PROTOTYPE
int operationSwitch(); //Function to calculate total of operand1 and operand2.
int menu(); //Function for main menu.
int iResume(); //Function to continue the program or not.
char iOperation = '\0'; //choices (1-7)
float operand1 = 0; //number 1
float operand2 = 0; //number 2
float operandTotal = 0; //total
int testPrime, counter, prime = 0;
char cContinue = '\0';
char symbol = '\0';
int main(){
menu();
return 0;
}
int menu (){
do {
printf("\nPlease choose an operation: ");
printf("\n(1) Addition\n ");
printf("\n(2) Subtraction\n ");
printf("\n(3) Multiplication\n ");
printf("\n(4) Division\n ");
printf("\n(5) Modulus (integers only)\n ");
printf("\n(6) Test if Prime (integers only)\n ");
printf("\n(7) Exit\n ");
printf("\nChoose (1-7):\t");
fflush(stdin);
scanf(" %c", &iOperation);
} while (iOperation < 49 || iOperation > 55 );
if (iOperation != 54 && iOperation != 55){ //ASCII 55 == 7)
printf("\nEnter number 1:\t");
fflush(stdin);
scanf(" %f", &operand1);
printf("\nEnter number 2:\t");
fflush(stdin);
scanf(" %f", &operand2);
}
operationSwitch();
/*** RESULTS ***/
if ( symbol == '/' && operand2 == 0) {
printf("\n\t-----| Answer: %.2f / %.2f = Undefined |-----\n", operand1,operand2);
} else if (iOperation != 54) {
printf("\n\t-----| Answer: %.2f %c %.2f = %.2f |-----\n", operand1, symbol, operand2, operandTotal);
}
iResume();
return 0;
} //End Menu
/*********************************
SWITCH FUNCTION
*********************************/
int operationSwitch() {
switch (iOperation) {
case 49://1 Addition Ascii 49 == 1 43 == +
operandTotal = operand1 + operand2;
symbol = '+';
break;
case 50: //2 Substraction
operandTotal = operand1 - operand2;
symbol = '-';
break;
case 51: //3 Multiplication
operandTotal = operand1 * operand2;
symbol = '*';
break;
case 52: //4 Division
operandTotal = operand1 / operand2;
symbol = '/';
break;
case 53: //5 Modulus
operandTotal = (int)operand1 % (int)operand2;
symbol = '%';
break;
case 54: //6
prime = 1;
printf("\nEnter number to be tested for prime: ");
fflush(stdin);
scanf(" %d", &testPrime);
for(counter = 2; counter <= (testPrime/2); counter++ )
{
if(testPrime % counter == 0)
{
prime = 0;
break;
}
}
if (prime == 1) {
printf("\n\t| %d is a prime number. |\n", testPrime);
}
else {
printf("\n\t| %d is not a prime number. |\n", testPrime);
printf("\n\t| %d * %d = %d \n", testPrime/counter, counter , testPrime);
}
break;
case 55:
printf("\nGood Bye\n");
exit(0);
break;
default:
printf("\nYou entered: %c - Please try again ", iOperation );
break;
} //End Switch iOperation
return 0;
} //End Switch Function
/*********************************
RESUME FUNCTION
*********************************/
int iResume() {
printf("\nWould you like to try again?\nPress \'Y\' to go to menu,\nor any key to quit?\t");
fflush(stdin);
scanf(" %c", &cContinue);
if (cContinue == 'y' || cContinue == 'Y'){
menu();
} else {
printf("Good Bye!\n" );
}
return 0;
}
fflush(stdin) is undefiined behavior.
int fflush(FILE *ostream);
ostream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes
any unwritten data for that stream to be delivered to the host
environment to be written to the file; otherwise, the behavior is
undefined.

Searching through struct array for string entered by user

This is just a function from my program that is supposed to search for the string or integer the user enters in the struct array. What I'm trying to do is add an error message and the ability to try again when that entered string or integer is not found in the struct array. It searches just fine if you enter the correct string or integer but nothing happens if you don't. I'm trying to change that but can't find the solution.
I've tried for a while now with one of the cases in my switch statement but I need to do it for all three. But so far I've only tried on case 3.
search(struct items aItems[], int *num_items)
{
int choice_of_search, b=0, found_word=0, search_num, i=0, j=0, k=0;
char search_phrase[20]; struct items search[MAX];
printf("Choose what to search for? (1) Item number, (2) Name and (3) Balance. ");
scanf("%d", &choice_of_search);
while(choice_of_search < 1 || choice_of_search > 3)
{
printf("Wrong choice!\n");
printf("Choose what to search for? (1) Item number, (2) Name and (3) Balance. ");
scanf("%d", &choice_of_search);
}
switch(choice_of_search)
{
case 1:
printf("Item number?\n");
scanf("%d", &search_num);
for(i = 0; i < *num_items; i++)
{
if(search_num == aItems[i].itemnumber)
{
printf("Item number found!\n");
search[found_word]=aItems[i];
found_word+=1;
}
}
break;
case 2:
printf("Name?\n");
scanf("%s", search_phrase);
for(i = 0; i < *num_items; i++)
{
if(strstr(aItems[i].name, search_phrase))
{
printf("Name found!\n");
search[found_word]=aItems[i];
found_word+=1;
}
}
break;
case 3:
printf("Balance?\n");
scanf("%d", &search_num);
for(i = 0; i < *num_items; i++)
{
if(search_num == aItems[i].balance)
{
printf("Balance found!\n");
search[found_word]=aItems[i];
found_word+=1;
}
else
{
printf("Balance not found! Try again.\n");
printf("Balance?\n");
scanf("%d", &search_num);
}
}
break;
}
while(b < found_word)
{
printf("Item number: %d Name: %s Balance: %d\n", search[b].itemnumber, search[b].name, search[b].balance);
b++;
}
}
Maybe this can help
int done;
...
...
case 3:
done = 0;
while(1);
{
printf("Balance?\n");
scanf("%d", &search_num);
for(i = 0; i < *num_items; i++)
{
if(search_num == aItems[i].balance)
{
printf("Balance found!\n");
search[found_word]=aItems[i];
found_word+=1;
done = 1;
}
}
if (done) break;
printf("Balance not found! Try again.\n");
}
break;
But notice that the code isn't user friendly as it doesn't allow the user a way to stop the search without a match. So maybe you should consider adding a "Would you like try again" option.
A simple approach could be
printf("Balance not found! Would like to try again?.\n");
scanf(" %c", &some_char);
if (some_char != 'y') break;

C while showing two times before stop

This is the called Function:
int onBattle(int level,char nomeheroi[20])
{
const char *monsternames[4][3] = {
{"Rat","Bat","Spider"},
{"Goblin","Orc","Dwarf"},
{"Dragon","Lich","Banshee"},
{"Demon","Hydra","Giant Spider"}
};
//printf("monster hp:%f , player hp:%f, player name:%s ",globalvar.monterhp, globalvar.playerhp,nomeheroi);
char opcaobattle;
rndMonster(level);
while((globalvar.monterhp > 0) || (globalvar.playerhp > 0)){
printf("Monster name:%s\n",monsternames[globalvar.monstercatego][globalvar.monsternivel]);
printf("Monster Life:%f\n",globalvar.monterhp);
printf("------------------------------------------\n");
printf("----------------BattleGround--------------\n");
printf("------------------------------------------\n");
printf("Player name:%s\n", nomeheroi);
printf("Player life:%f\n", globalvar.playerhp);
printf("----------------------------------------\n");
printf("------------------Menu------------------\n");
printf("----------------------------------------\n");
printf("A - Attack\n");
printf("D - Defend\n");
scanf("%c",&opcaobattle);
switch(opcaobattle)
{
case 'a':
danoPMonster();
break;
case 'd':
break;
}
}
if(globalvar.monterhp <= 0)
{
return 0;
}
else if(globalvar.playerhp <= 0)
{
return 1;
}
}
This is what happen:
I dont any problem with this code to show two times before stop on Scanf, i tried Do While too and the same thing happens any help?
ps: that globalvar is a global struct and yes there is a value
scanf("%c",&opcaobattle);
I suggest adding a space to the conversion specifier to make sure it isn't using a left-over newline character in the stream.
scanf(" %c",&opcaobattle);
It might be good to have a default case for the switch, too:
default:
printf("Please enter one of the available commands.\n");

Resources