Im a beginner to C and I'm having trouble with structs.
after I've asked user for all attributes, id like to print all the values of the struct. The problem is that after I've got input all the attributes to a struct and it loops back again to ask for attributes a second time, the first struct input gets replaced by the second struct input.
I'm pretty sure that I'm allocating the same memory space over and over and thus causing the problem but I'm stuck on how to fix it. Id appreciate any advice on what i can do. thanks!
case 2:
printf ("Please input a SKU number:");
scanf ("%d", &item[MAX_ITEMS].sku_);
printf ("Quantity:");
scanf ("%d", &item[MAX_ITEMS].quantity_);
printf ("Price:");
scanf ("%f", &item[MAX_ITEMS].price_);
printf ("The item is successfully added to the inventory");
break;
to print out the sku, quantity and price
switch (menuSelection) {
case 1:
printf ("Inventory\n");
printf ("=========================================\n");
printf ("Sku Price Quantity\n");
for (i =0 ; i<=MAX_ITEMS; i++){
printf ("%d %.2f %d\n", item[i].sku_, item[i].price_, item[i].quantity_);
}
printf ("=========================================\n");
break;
here is my whole code:
#include <stdio.h>
#define MAX_ITEMS 10
struct Item{
int sku_;
float price_;
int quantity_;
}item[MAX_ITEMS];
int main (void) {
int size=0;
int menuSelection;
int i=0;
printf ("Welcome to the Shop\n");
printf ("===================");
do {
printf ("\nPlease Select from the following options:\n");
printf ("1) Display the inventory.\n");
printf ("2) Add to shop.\n");
printf ("0) Exit.\n");
printf ("select:");
scanf ("%d", &menuSelection);
if (menuSelection <0 && menuSelection >2){
printf ("Invalid input, try again: Please select from the following options:");
}
else {
switch (menuSelection) {
case 1:
printf ("Inventory\n");
printf ("=========================================\n");
printf ("Sku Price Quantity\n");
for (i =0 ; i<=MAX_ITEMS; i++){
printf ("%d %.2f %d\n", item[i].sku_, item[i].price_, item[i].quantity_);
}
printf ("=========================================\n");
break;
case 2:
printf ("Please input a SKU number:");
scanf ("%d", &item[size].sku_);
printf ("Quantity:");
scanf ("%d", &item[size].quantity_);
printf ("Price:");
scanf ("%f", &item[size].price_);
printf ("The item is successfully added to the inventory");
break;
case 3:
break;
}
}
} while (menuSelection != 0);
return 0;
}
You create an array of Item objects with the length of MAX_ITEMS, currently being 10. That is, your objects have the indices of 0 to 9. Yet when asking the user for input, you always store the data at item[MAX_ITEMS] which is out of bounds of your array.
As a side note, when printing your array, you always print it whole, meaning also uninitialised items.
You have to store how many items are already "added to the shop" and use this number to determine the next array index where user input has to be stored. When printing you only have to iterate over the items already stored. Don't forget bounds checking, e.g. don't allow new user input when your shop is full.
The problem is that you always save the new values in the same place:
item[MAX_ITEMS].sku_
Instead, you should have a counter that show how many items are stored and save the new values in the place that is equal to the counter:
item[counter].sku_
and after every insertion you should increase the counter:
counter++;
So, your code should look like this:
int counter=0;
...
case 2:
printf ("Please input a SKU number:");
scanf ("%d", &item[counter].sku_);
printf ("Quantity:");
scanf ("%d", &item[counter].quantity_);
printf ("Price:");
scanf ("%f", &item[counter].price_);
printf ("The item is successfully added to the inventory");
counter++;
break;
I hope I was helpful
The item you defined is a array with size of MAX_ITEMS, so the problem of you is not about struct but array.
In most of computer programming language, indexing an array should use a offset start on zero. That is, MAX_ITEMS of item[MAX_ITEMS] is out of range for the array, you got a bug and do not find it. When you adding a item to your shop, you should code like this:
case 2:
if (last < MAX_ITEMS - 1)
{
printf ("Please input a SKU number:");
scanf ("%d", &item[last].sku_);
// ...
last ++; // on success
}
else
{
print("oops, shop is full.");
}
Related
I'm making a program that takes data from various rockets (except their first stage engines) and calculates dV with a new, substitute engine.
Here is the code:
#include <stdio.h>
#include <math.h>
main () {
int choice;
do {
printf ("\n1-Register rocket data");
printf ("\n2-Change already registered data");
printf ("\n3-Delete rocket data");
printf ("\n4-Show registered rockets");
printf ("\n5-Register substitute engine data");
printf ("\n6-Calculate dV with substitute engine");
printf ("\n0-End");
scanf ("%d", &choice);
switch(choice) {
case 1:
dV();
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
}
} while(choice != 0);
}
dV () {
int count, x, i;
float rockets[] , dV, wetMass, dryMass, Isp;
printf ("How many rockets will be registered?");
scanf ("%d", &x);
while (i == 1) {
for (count=1; count <= x; count++)
printf ("\n\nWet Mass(kg): ");
scanf ("%f", &wetMass);
fflush (stdin);
printf ("Dry Mass: ");
scanf ("%f", &dryMass);
fflush (stdin);
printf ("Specific Impulse(Seconds): ");
scanf ("%f", &Isp);
fflush (stdin);
printf ("\nType 1 to add a stage or 0 to end the process: ");
scanf ("%d", &i);
dV = (Isp * 9.8 * log(wetMass/dryMass) + dV);
dV = rockets[x++];
}
}
The error:
error: array size missing in 'rockets' (line 50)
Warnings:
warning: implicit declaration of function 'dV' [-Wimplicit-function-declaration} (line 22)
warning: return type defaults to 'int' (Wimplicit-int) (line 47)
First question: How do I solve these errors and warnings?
Second question: How can I make a vector with user-defined number of elements? The user has to be able to register as many rockets as they want. My plan is to calculate the dV for each rocket and store it in an element of the rocket[] vector after the substitute engine data is provided.
Third question: How can I change the value of an already defined element in a vector?
Fourth question: How can I assign vector elements progressively? By that I mean: First registered rocket data should go to rockets[0], the second to rockets[1], etc.
edit: I forgot to add this after line 55
printf ("\ntype 1 to add a stage or 2 to end the process: ");
scanf ("%f", &i);
To remove errors and warnings, do changes as below i.e. create float array of rockets after you fetched value of x and initialize i by 1 before using it in while and add void in return type of dV function if any return value not needed.
void dV () {
int count, x, i;
float dV, wetMass, dryMass, Isp;
printf ("How many rockets will be registered?");
scanf ("%d", &x);
float rockets[x];
i=1;
while (i == 1) {
.
.
}
Answer to your second question : either make rockets as global array or return it to main through dV function.
I am creating a little scoring program and am having trouble with this case. When I enter an 'e', it breaks correctly as the default suggests, but then it runs through the first switch statement, and then exits the program..
This only happens when I enter the letter 'e'. If i enter 'q' or anything else, it doesnt exit ?
case 'd': // Field Competition Logs
{
int fieldRound;
int ifaaField[2], ifaaFieldTotal;
int ifaaHunter[2], ifaaHunterTotal;
int fitaField[1];
int field3D[1];
printf ("Please select the type of round you shot\n\n");
printf ("\t(a) IFAA Field\n\t(b) IFAA Hunter\n\t(c) Fita Field\n\t(d) 3D Field\n> ");
scanf (" %d", &fieldRound);
switch (fieldRound)
{
case 'a': // Ifaa Field Round
{
printf ("Please enter the score for your first round > ");
scanf (" %d", &ifaaField[0]);
printf ("Please enter the score for your second round > ");
scanf (" %d", &ifaaField[1]);
ifaaFieldTotal = ifaaField[0] + ifaaField[1];
printf ("Total of your first half (%d) and your second half (%d) is %d", ifaaField[0], ifaaField[1], ifaaFieldTotal);
break;
}
case 'b': // Ifaa Hunter Round
{
printf ("Please enter the score for your first round > ");
scanf (" %d", &ifaaHunter[0]);
printf ("Please enter the score for your second round > ");
scanf (" %d", &ifaaHunter[1]);
ifaaHunterTotal = ifaaHunter[0] + ifaaHunter[1];
printf ("Total of your first half (%d) and your second half (%d) is %d", ifaaHunter[0], ifaaHunter[1], ifaaHunterTotal);
break;
}
case 'c': // Fita Field Round
{
printf ("Please enter your Fita Field score > ");
scanf (" %d", &fitaField[0]);
printf ("Total of your Fita Field round is %d", fitaField[0]);
break;
}
case 'd': // Field 3D Round
{
printf ("Please enter your 3D Field score > ");
scanf (" %d", &field3D[0]);
printf ("Total of your 3D Field round is %d", field3D[0]);
break;
}
default:
printf ("Please enter a valid response");
break;
}
break; // Breaks out of Case D
}
case 'e': // Exits the program
{
printf ("Thank you, Good bye!\n");
return 0;
}
OUTPUT
Please select the type of round you shot
(a) IFAA Field
(b) IFAA Hunter
(c) Fita Field
(d) 3D Field
> e
Please enter a valid response
Hi s. c, Please choose from the following options by typing the letter and pressing the 'return' key
(a) Enter Scored Practice logs
(b) Enter Practice Arrow count
(c) Enter Competition logs
(d) Enter Field Competition Logs
(e) Exit Program
> Thank you, Good bye!
scanf (" %d", &fieldRound);
This scanf fails! It expects numeric input, not an alphabetic character!
Change
scanf (" %d", &fieldRound);
to
scanf (" %c", &fieldRound);
In your current configuration, your scanf expects a decimal number, not a character. It thusly fails if you try inputting a character.
Additionally, you need to change int fieldRound; to char fieldRound;.
this is a follow on question from one I asked recently:
C Programming help - providing user with option to exit a program
I now have a new problem. I can get the program to exit if a user enters any letter which is great, but now if a number is entered nothing happens. The while loop doesn't seem to run..
Can you please have a look at my code and see if you can spot what's wrong, thanks. Also, ideally i'd like xterm's window to close if the user wishes to exit. I'd be greatful if anyone could show me how to do this. Anyway here's the code:
#include <stdio.h>
#include <stdlib.h>
int main()
{
float number;
float sum = 0;
printf ("Please enter number or enter any letter to exit:\n");
scanf ("%f", &number);
// if user ENTERS a letter, program will terminate
if(1!=scanf ("%f", &number))
{
getchar();
printf ("Exiting the program...\n");
exit(0);
}
while (1)
{
sum += number;
printf ("Sum: %.2f\n", sum);
printf ("Please enter number or enter any letter to exit:\n");
scanf ("%f", &number);
// if user ENTERS a letter, program will terminate
if(1!=scanf ("%f", &number))
{
getchar();
printf ("Exiting the program...\n");
exit(0);
}
}
return 0;
}
As #BrianCain commented: you are calling scanf a second time in your if statement. If you entered a letter for the first scanf, it forces the second to immediately fail; if you entered a number for the first, then the second is waiting for you to enter another number.
I removed two of your scanf functions and it seems to fix the problem
#include <stdio.h>
#include <stdlib.h>
int main()
{
float number;
float sum = 0;
printf ("Please enter number or enter any letter to exit:\n");
// if user ENTERS a letter, program will terminate
if(1!=scanf ("%f", &number))
{
getchar();
printf ("Exiting the program...\n");
exit(0);
}
while (1)
{
sum += number;
printf ("Sum: %.2f\n", sum);
printf ("Please enter number or enter any letter to exit:\n");
// if user ENTERS a letter, program will terminate
if(1!=scanf ("%f", &number))
{
getchar();
printf ("Exiting the program...\n");
exit(0);
}
}
return 0;
}
The scanf in your if erased the value of the previous one you did.
While the previous two answers are essentially correct, the simple (and clear) version would be:
if(number == 1)
break;
Place this right after your original scanf() and get rid of the other if(..) ..; condition entirely. This will test to see if the number '1' was entered, and if so will break the infinite loop, allowing the program to continue down to the return 0; statement.
It will also deal with what could be confusing style, which is having an exit condition (the final return 0;) that's essentially impossible to get to, or should be.
hello guys I coded something like kfc menu,and I got it to work(finally),but when I input something other than numbers for "menu",eg:the letter "A", I just can't get it to loop again to normal,instead it finishes the program
#include <stdio.h>
#include <stdlib.h>
int main()
{
char counter='y';
float totalprice=0;
while (counter=='Y' || counter=='y')
{
int menu;
float price=0;
printf("\nplease select from menu:");
scanf (" %i", &menu);
switch(menu)
{
case 1: {
printf("\none hotbox1 =RM10.50");
totalprice=totalprice+10.50;
break;
}
case 2: {
printf ("\none hotbox2=RM10.60");
totalprice=totalprice+10.60;
break;
}
case 3:{
printf ("\none hotbox3=RM10.70");
totalprice=totalprice+10.70;
break;
}
default : {
printf ("\nplease enter proper number please:");
scanf("%2f", &menu);
break;
}
}
printf("\n\nadd order?(Y/N):");
scanf (" %c", &counter);
}
printf("\n\nThe total price is: %f", totalprice);
return 0;
}
You should use fgets() (reference here) first and then sscanf() (reference here), checking it's return value to see if it's a number.
char inputBuffer[MAX_BUFFER];
do
{
fgets(inputBuffer, MAX_BUFFER, stdin);
}
while(sscanf(inputBuffer, "%d", &menu) != 1)
You scanf with %f in the default case, I am fairly certain that is for floats. Use %d.
Remove scanf("%2f", &menu);
Switch in C does not support char in switch-case. Before you start switch-case validate the user input. If it is a number go into switch case otherwise display a user message to enter only numeric value
I recommend that you debug this by printing out the value of "counter" at various points in the loop (i.e. after you read it in, at the bottom of the loop, etc.). This will give you visibility into what your code is doing.
You can try something like this
#include <stdio.h>
int main()
{
char counter;
float totalprice=0;
int menu=0;
do
{
printf("\n1. one hotbox1=RM10.50");
printf("\n2. one hotbox2=RM10.60");
printf("\n3. one hotbox3=RM10.70");
printf("\nplease select from menu:");
scanf ("%d", &menu);
switch(menu)
{
case 1:
printf("\none hotbox1 =RM10.50");
totalprice=totalprice+10.50;
break;
case 2:
printf ("\none hotbox2=RM10.60");
totalprice=totalprice+10.60;
break;
case 3:
printf ("\none hotbox3=RM10.70");
totalprice=totalprice+10.70;
break;
default :
printf ("\nplease enter proper number please:");
scanf("%d", &menu);
}
printf("\n\nadd more order?(Y/N):");
fflush(stdin); //to empty the input stream.
scanf("%c",&counter);
}while(tolower(counter) != 'n'); //tolower returns the lowercase character.
printf("\n\nThe total price is: %.2f", totalprice);
return 0;
}
When scanf("%i", &menu) tries to read an integer from the input, it finds A, which it cannot interpret as a number, so it does not read it(*). Then the next scanf continues reading the input from when the other left off and happily reads the letter 'A'. Since you loop as long as the read letter is either 'y' or 'Y' (which A is neither), it exits the loop.
(*) read up on the documentation of scanf to see how to tell if it encountered an error.
Note: scanf("%i", &menu) should be scanf("%d", &menu) as%d` is the formatting symbol for integers.
One solution would be to change the loop condition to:
while (counter!='N' && counter!='n')
{
...
}
This way you end the loop only if an explicit 'N' or 'n' is inputted.
Note: it won't help if you accidentally type 'n' for the menu item, so see the comment about the error handling above.
This question already has answers here:
Simple C scanf does not work? [duplicate]
(5 answers)
Closed 9 years ago.
I have written a simple program to exchange currency and able to buy a beer.
But there something in program and I don't know why, it auto skips the third input data -> end program.
Here my code :
#include <stdio.h>
#include <stdlib.h>
int main()
{
int ex_rate_into_vnd = 20000; //! Exchange Rate
int beer = 7000; //! Local price of a beer
float in_c = 0; //! Input amount of money
float out_c = 2; //! Amount of currency to exchange !
float choice; //! Switch mode
char buy; //! Deal or not
//! Introduction
printf ("||---------------------------------------------------||\n");
printf ("|| Currency Exchange Machine beta ||\n");
printf ("||---------------------------------------------------||\n");
printf ("Please choose your option:\n");
printf("\t 1.Exchange VND to dollar\n");
printf("\t 2.Exchange Dollar to VND\n");
do
{
printf("Your choice: ",choice);
scanf("%f",&choice);
} while( choice != 1 && choice != 2);
printf ("Please enter amount of money:");
scanf("%f",&in_c);
if (choice == 1 )
{
out_c = in_c / ex_rate_into_vnd;
printf ("Your amount of money: %.2f",out_c);
}
else
{
out_c = in_c * ex_rate_into_vnd;
printf ("Your amount of money: %.0f",out_c);
}
//! End of Exchanging
printf ("\nWould you like to buy a beer (y/n) ?",buy);
scanf("%c", &buy);
if (buy == 'y')
{
if (out_c >= 7000)
{
out_c = out_c - 7000;
printf("Transactions success !\n");
printf("Your amount: %2.f",out_c);
}
}
printf ("\nWhy Stop ?");
return 0;
}
You have at least one \n between the latest float entry and the char you want to read. You need to get rid of that first.
See also all answers in getchar after scanf category
Change
scanf("%c", &buy);
to
scanf(" %c", &buy);
// ^space
Because the newline character is still in the input buffer after you enter a number and press ENTER in the second scanf.
Instead of scanf("%c", &buy);
1.use space before %c
scanf(" %c",&buy); //space before %c
^
this skips reading of white space (including newlines).
2.or Use getchar(); before scanf("%c", &buy); statement
getchar(); //this hold the newline
scanf("%c", &buy);
3.or use two times getchar();
getchar();
buy=getchar();
//here getchar returns int , it would be better if you declare buy with integer type.
In GCC usage of fflush(stdin); is discouaraged. please avoid using it.
I was wondering why you made 'choice' a float, not an int
Also, consider using a switch-case
that way, you won't have to do the whole do-while loop.
Also, in the line
printf ("\nWould you like to buy a beer (y/n) ?",buy);
Why did u add that?
Here is what I would have done :
printf("Your choice?\n>");
scanf("%d", &choice);
switch(choice)
{
case 1 :
{
out_c = in_c / ex_rate_into_vnd;
printf ("Your amount of money: %.2f",out_c);
}
case 2:
{
out_c = in_c * ex_rate_into_vnd;
printf ("Your amount of money: %.0f",out_c);
}
default :
printf("\nThere has been an error\n"):
reloadprogram(); /* Reloadprogram() is simply to make this go back to the asking thing :) */
}
}
EDIT: also, where it says if( <somevariable> >= 7000), change 7000 to beer, so that way, if u change beer, you won't have to change this :)
Put a fflush(stdin) to clear the input before the last scanf
The program doesn't skip the third input data, it just scans the newline you press after the second input. To fix this, type scanf("%*c%c", &buy); instead of scanf("%c", &buy);. This little %*c scans and ignores the the character read from the input.
you can remove the buy variable from the printf call, it's unneeded
printf ("\nWould you like to buy a beer (y/n) ?",buy);
And replace char buy by char buy[2]; . because a sting is always terminated by /0.
You can also add a memset (buy, 0, sizeof(buy)), to be sure that memory is reset before you start to use it.