Why is the price increase always zero? - c

I need some help with a program I've been making for the university. Inside this program, it must be a function that must increase the price of a type of product according to a value given by the user. Fine, I've written the following function:
void increase_price(struct reg products[SIZE], int count){
int i;
float increase, perc;
char option;
printf("Type of product: ");
fflush(stdin); scanf("%c", &option);
printf("\nThe increase percentage: ");
fflush(stdin); scanf("%f", &perc);
for(i=0; i<count; i++){
if(products[i].type == option){
increase = products[i].price * (perc/100);
products[i].price += increase;
}
}
}// Fim increase_price()
The problem is that the increase's calculation always results in zero. I can't understand why it's happening. I also tried to print the 'perc' variable after receiving its input, but strangely it didn't work.
Some more code:
The definition of struct reg:
#include <stdio.h>
#include <conio.h>
#define SIZE 100
struct reg{
int cod;
char desc[30], type;
float price;
};
At the main function, the only usefull thing for this function is the call of the function itself, and, sure, the declaration of the struct and the count variable(whose value comes from another function according to the number of products).
The type is defined in another function in which you can add products. it's a litteral value like P (for pants), T (for T-shirt) etc.

Related

The scanf is not reading the values

Hey this is the entire code.
I m a beginner in C, I was trying to make a code which has a structure mall and takes into input the name, number of items shopped , the name of each item and the cost of each item.
* For small programs like this i fix the max size of the structure object
But the program cant take the input in the manner desired.
#include<stdio.h>
struct mall
{
char name[50];
char obj[10][30];
float price[10];
int numb;
}b[50];
void main()
{
int m; // number of persons who shopped at the mall
scanf("%d",&m);
for(int i=0;i<m;i++)
{
num=0;
scanf("%s",&b[i].name);
scanf("%d",&b[i].numb);
printf("%s\n%d",b[i].name,b[i].numb);
for(int j=0;j<num;j++)
{
scanf("%s",&b[i].obj);
scanf("%f",&b[i].price);
}
}
}
For the input :
1
Ram 2 bread 50.00 jam 25.00
I m getting the output as
2500
Your code has many small mistakes:
scanf("%s", &b[i].name); does not need &
num=0; is not necessary; remove it
Nested loop condition should use j < b[i].numb as its condition
Nested loop is not using j. It needs to add [j] to both obj and price.
Once you fix these problems, your code runs as expected as long as the input is correct (demo).
However, this is not enough to make your code robust: you need to add error checking to ensure that invalid input does not cause undefined behavior:
Add limits to string format specifiers in scanf to avoid buffer overflows (e.g. %49s to read name[50]),
Add a limit to the outer loop in case m is above 50,
Add a limit to the nested loop in case b[i].numb is above 10,
Add checks of return values for scanf.
num is undeclared. The program does not compile to executable. See below.
Don't pass &b[i].name to scanf(3), as the %s format requires a char * and the &b[i].name is not that type (it is, indeed, char *[50], while compatible, it is not the same type, while b[i].name is)
change num by b[i].numb in the inner for loop. This is the proper number of items. You have to check for array sizes also, as you have hardwired them in the code. If you don't you can overrun
Use inside the inner loop b[i].obj[j] for the object name as the reference to scanf(3)
Use inside the inner loop &b[i].price[j] for the j-esim price. You have forgotten it here and in the point above.
you have to add code to print the individual objects (the inner loop has no printf(3) at all.
A valid (but not completely correct, as array sizes are not checked) could be:
#include<stdio.h>
struct mall {
char name[50];
char obj[10][30];
float price[10];
int numb;
}b[50];
int main()
{
int m; // number of persons who shopped at the mall
scanf("%d",&m);
for(int i=0; i<m; i++) {
scanf("%s",b[i].name);
scanf("%d",&b[i].numb);
printf("* name = %s\n"
" numb = %d\n",b[i].name,b[i].numb);
for(int j=0; j < b[i].numb; j++) {
scanf("%s",b[i].obj[j]);
scanf("%f",&b[i].price[j]);
printf(" * obj = %s\n", b[i].obj[j]);
printf(" price = %.2f\n", b[i].price[j]);
}
}
return 0;
}

C program that results in a static and non-static declaration error

Here is the code from my program that has a issue:
#include "stdio.h"
int main(void)
{
int funcnum;
printf("Welcome \n");
printf("Please enter a number\n");
scanf("%i",&funcnum);
switch(funcnum) //funcnum is the variable you are checking for a match
{ //Open curly!
case 1: // is funcnum==1?
printf("You entered 1. This is now the Turkey Time function.\n"); // if funcnum==1, this will happen.
{
//DECLARE the "cookTime" function.(Above, outside the MAIN function)
//It will return a float, and is expecting two floats.
float cookTime (float);
//Below is a "global" variable -meaning available to all functions. These are declared outside of any function.
float cTim;
float weight;
printf("Welcome to the turkey timer...\n");
printf("Please enter a turkey weight \n");
scanf("%f",&weight);
cookTime (weight); //Calling (jumping to) the cookTime function and sending it "weight" variable.
printf("Cooking time is %.1f minutes.\n\n",cTim); //printing the returned value cTim.
printf("\tThank you for choosing the MaiCorp Timing System, don't forget the gravy! \n");
//DEFINE the function. Note -no semicolon. (just like in main's definition above!)
float cookTime (float w)
{
cTim = w*15;
return cTim; //We are sending cTim back to where we left Main.
}
}
break; //break makes the statement end and jump out of the curlies.
case 2: // is funcnum==2?
printf("You entered 2. This is now the Area function.\n");
{
//DECLARE the "area" function.(Above, outside the MAIN function)
//Looking at the declaration we can see that this function will return an int, and is expecting two int's.
int area (int, int);
//Here we declare a global variable. Meaning a variable that is available to all functions. These are declared outside of any function.
int ans;
int len,wid;
printf("Welcome to the rectangle area calculator...\n");
printf("Please enter a length\n");
scanf("%i",&len);
printf("Please enter a width\n");
scanf("%i",&wid);
area (len,wid); //Calling the "area" function, sending it the len and wid integers..
printf("Area is %i.\n",ans); //printing the returned value "ans"
//DEFINE the area function. Note -no semicolon. (just like in main's definition above!)
int area (int L, int W)
{
ans = L*W;
return ans;
}
}
break;
default: //default catches all non matches.
printf("You did not enter 1 or 2, meaning that you are not running a function this time.\n");
break;
} //close curly!
return 0;
}
When I run this program, the gcc version 4.6.3 compiler gives this:
main.c: In function 'main':
main.c:35:21: error: static declaration of 'cookTime' follows non-
static declaration
float cookTime (float w)
^~~~~~~~
main.c:17:21: note: previous declaration of 'cookTime' was here
float cookTime (float);
^~~~~~~~
main.c:67:19: error: static declaration of 'area' follows non-static
declaration
int area (int L, int W)
^~~~
main.c:47:19: note: previous declaration of 'area' was here
int area (int, int);
^~~~
exit status 1
This program is written in C in case anyone needs to know the programming language that the program is written in.
I have tried to fix the program by putting in "{}"'s and other code but it came to be of no use (meaning that the error did not resolve).
It would be great if a reputable programmer can assist me with this issue.
It looks like you are declaring a function within the main...? That is not only bad practice, but judging by the code there it looks like it's illegal. Unless you put static in front of it.
If you want to use the function, do NOT put it's return type before using the function. Instead of:
int area( int L, int W);
use
area(int L, int W);
Really weird to define a function within the main. Like I said, I don't think it's allowed, but if you REALLY want to do it, I would suggest putting static in front of the function.
Better yet, make a Name_goes_here.h file and put the functions in there. Then,
#include "Name_goes_here.h"
and use the functions like I told you. (except instead of int L, int W, replace it with pre-declared variables L and W without int in front of it.)
the following proposed code:
cleanly compiles.
properly prototypes the sub functions.
properly declares the sub functions.
eliminates most commentary that is just a repeat of the code.
Uses appropriate vertical spacing (between code blocks, between functions, between code activities).
fails to check the returned value from system functions (I.E. scanf()).
Follows the axiom: only one statement per line and (at most) one variable declaration per statement.
respects the right boundary of a printed output of the listing.
properly writes a 'float' literal
and now the proposed code:
#include "stdio.h"
// prototypes
int area (int, int);
float cookTime (float);
int main(void)
{
int funcnum;
printf("Welcome \n");
printf("Please enter a number\n");
scanf("%i",&funcnum);
switch(funcnum)
{
case 1:
printf("You entered 1."
" This is now the Turkey Time function.\n");
float weight;
printf("Welcome to the turkey timer...\n");
printf("Please enter a turkey weight \n");
scanf("%f",&weight);
float cTim = cookTime (weight);
printf("Cooking time is %.1f minutes.\n\n",cTim);
printf("\tThank you for choosing the MaiCorp Timing System, don't forget the gravy! \n");
break;
case 2:
printf("You entered 2."
" This is now the Area function.\n");
int len;
int wid;
printf("Welcome to the rectangle area calculator...\n");
printf("Please enter a length\n");
scanf("%i",&len);
printf("Please enter a width\n");
scanf("%i",&wid);
int ans = area (len,wid);
printf("Area is %i.\n",ans);
break;
default:
printf("You did not enter 1 or 2,"
" meaning that you are not running"
" a function this time.\n");
break;
}
return 0;
} // end function: main
int area (int L, int W)
{
int ans = L*W;
return ans;
} // end function: area
float cookTime (float w)
{
float cTim = w*15.0f; // << note the proper 'float' literal
return cTim;
} // end function: cookTime

Defining a variable vs. initializing

So, I am led to believe by my professor that when declaring the size of an array, it is best to use #define vs. just declaring it as a normal integer. Is this correct?
If so, why?
Also, if this is correct, what am I doing wrong? When I try to do this I get an message:
error: expected ';', ',' or ')' before numeric constant
every time I call the array. The code works if I just initialize it as an integer.
The definition and usage can be seen in the following code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define handsize 5
#define size 52
// Create function prototypes
void create_deck (int deck[]);
void shuffle_deck (int size, int deck[]);
void display_card (int card);
void display_hand (int size, int hand[]);
int popCard (int *size, int deck[]);
int findScore (int size, int hand[]);
int main()
{
// declare/ initialize variables
int c, d, p, win = 0, lose = 0 , tie = 0, /*handsize = 0, size = 52,*/ deck[size], hand[handsize], dealer[handsize];
char play;
srand(time(NULL)); // attach random number generator to time function for truly random variables
// explain program to user and ask if they want to play
printf("This program is a card game that adds the values of all the\n");
printf("cards in the players hand, and the computers hand. The highest hand wins.\n");
printf("Would you like to play? Please press 'y' for yes, any other key for no.\n");
scanf("%c", &play); // if the user wants to play, continue the program
// while loop that continues as long as the user wants to play
while (play == 'y'){
// call functions to create and shuffle the deck
create_deck(deck);
shuffle_deck (size, deck);
// for loop that calls the popCard function to deal the top card in the deck
for (c = 0; c < 5; c++){
hand[c] = popCard (&size, deck); // player gets a card
dealer[c] = popCard (&size, deck); // computer gets a card
handsize++;
// call the display_hand function to display the individual cards in the players hand
printf("\nYour hand consists of:\n");
display_hand (handsize, hand);
// call the display_hand function to display the individual cards in the dealers hand
printf("Dealer hand consists of:\n");
display_hand (handsize, dealer);
}
// call the findScore function for both the user and the computer
p = findScore (handsize, hand);
d = findScore (handsize, dealer);
// show the value of the user and computers hands
printf("\nThe value of your hand is %i\n", p);
printf("\nThe value of the dealers hand is %i\n", d);
// if statements that keep track of wins, losses and ties
if (p > d)
win++;
if (p == d)
tie++;
if (p < d)
lose++;
// show number of times player has won, lost, tied. Then ask to play again
printf("You have won %i times, tied %i times, and lost %i times\n", win, tie, lose);
printf("\nWould you like to play again?\n");
fflush(stdin); // flush the input buffer to stop false readings
scanf("%c", &play); // read the user input to determine if they want to play again
}
printf("Goodbye");
return 0;
**I hope this is what you wanted
Symbolic constants (either #define or actual constants) are generally preferred.
What happens, for example, when your code is peppered with the value 1440 but you use that number for both twips per inch and kilobytes per floppy (very much showing my age here)?
Then all of a sudden your floppies become 2.88M. You then have to go through all your code looking for 1440 and figuring out if it meant the twips or kilobytes version, and changing the relevant ones. So not only do you have to make the change in multiple places (bad enough), you may also have to figure out whether the change you be made at each place.
Had you instead done:
#define TWIPS_PER_INCH 1440
#define KB_PER_FLOPPY 1440
and then peppered your code with the symbolic names, you could have then just changed one line, without too much thinking or analysis required.
There's a school of thought that any number other than zero or one (and possibly negative one) should have a symbolic constant of some sort. Just make sure you don't make the mistake of doing:
#define FOURTEEN_HUNDRED_AND_FORTY 1440
like one of my minions once tried. I had endless fun trying to explain why that was a bad idea :-)
As to your error, it's certainly possible to declare an array with a preprocessor constant as shown below:
#include <stdio.h>
#include <string.h>
#define VAR 42
int main (void) {
char xyzzy[VAR];
strcpy (xyzzy, "pax is awesome");
puts (xyzzy);
return 0;
}
However, consider the following lines in your code:
#define size 52
void shuffle_deck (int size, int deck[]);
void display_hand (int size, int hand[]);
int popCard (int *size, int deck[]);
int findScore (int size, int hand[]);
hand[c] = popCard (&size, deck);
// and possibly many others.
Because preprocessing is a textual substitution done early in the compilation process, those lines following the first are going to become:
void shuffle_deck (int 52, int deck[]);
void display_hand (int 52, int hand[]);
int popCard (int *52, int deck[]);
int findScore (int 52, int hand[]);
hand[c] = popCard (&52, deck);
and they will cause all sorts of problems, among them that 52 is not a valid variable name in a function prototype, and that you cannot take the address of an integer literal in C because it has no address.
In order to fix this, you define the initial size as a constant:
#define INIT_SZ 52
and use that to set the initial value of a variable size which you can later change, something like:
void doSomethingThatChangesSize (int *pSize) {
(*pSize) += 42;
}
int size = INIT_SZ; // this is the only way you use INIT_SZ
:
doSomethingThatChanges (&size);

program returning garbage values

This program is returning garbage values in output of total marks and average marks.
even after declaring s.total=0 and s.marks[15]=0 in the beginning of program
//student database
#include<stdio.h>
#include<conio.h>
#include<string.h>
main()
{
struct student
{
int name[20];
int roll[5];
int total;
float avg;
int marks[15];
};
struct student s;
int subject_no,i;
s.total=0;
s.marks[15]=0;
printf("Enter the name of student:\t");
scanf("%s",s.name);
printf("enter the roll no:\t");
scanf("%d",&s.roll);
printf("Enter the number of subjects:\t");
scanf("%d",&subject_no);
for(i=0;i<subject_no;i++)
{
printf("Enter marks in subject %d:\t",i);
scanf("%d",&s.marks);
s.total=s.total+s.marks[i];
}
printf("total marks are:%d\n",s.total);
s.avg=(s.total)/(subject_no);
printf("The average is :%d",s.avg);
getch();
}
This is an illegal memory access: s.marks[15]=0.
If you have 15 entries in the array, then legal indexes are between 0 and 14.
So you can do s.marks[0]=0 or s.marks[6]=0, but you should not do s.marks[15]=0.
If you want to set the entire array to zero values, then you can iterate it:
for (i=0; i<sizeof(s.marks)/sizeof(*s.marks); i++)
s.marks[i] = 0;
Or simply use memset:
memset(s.marks,0,sizeof(s.marks));
You should explicitly clear your s structure with
memset (&s, 0, sizeof(s));
Of course your filling of s.marks[15] is out of bounds (undefined behavior and/or buffer overflow!!)
Your code never fills or uses s.roll[1] so why make s.roll an array?
At last, your first for loop should be
if (subject_no >= 15) exit(EXIT_FAILURE);
for(i=0;i<subject_no;i++) {
printf("Enter marks in subject %d:\t",i);
scanf("%d",&s.marks[i]);
s.total=s.total+s.marks[i];
}
It would be better to store the name in a char array, rather than an int array (although that will work)
Also, you have been inconsistent in you use of scanf with arrays.

How can i add numbers to an array using scan f

I want to add numbers to an array using scanf
What did i do wrong? it says expected an expression on the first bracket { in front of i inside the scanf...
void addScores(int a[],int *counter){
int i=0;
printf("please enter your score..");
scanf_s("%i", a[*c] = {i});
}//end add scores
I suggest:
void addScores(int *a, int count){
int i;
for(i = 0; i < count; i++) {
printf("please enter your score..");
scanf("%d", a+i);
}
}
Usage:
int main() {
int scores[6];
addScores(scores, 6);
}
a+i is not friendly to newcomer.
I suggest
scanf("%d", &a[i]);
Your code suggests that you expect that your array will be dynamically resized; but that's not what happens in C. You have to create an array of the right size upfront. Assuming that you allocated enough memory in your array for all the scores you might want to collect, the following would work:
#include <stdio.h>
int addScores(int *a, int *count) {
return scanf("%d", &a[(*count)++]);
}
int main(void) {
int scores[100];
int sCount = 0;
int sumScore = 0;
printf("enter scores followed by <return>. To finish, type Q\n");
while(addScores(scores, &sCount)>0 && sCount < 100);
printf("total number of scores entered: %d\n", --sCount);
while(sCount >= 0) sumScore += scores[sCount--];
printf("The total score is %d\n", sumScore);
}
A few things to note:
The function addScores doesn't keep track of the total count: that variable is kept in the main program
A simple mechanism for end-of-input: if a letter is entered, scanf will not find a number and return a value of 0
Simple prompts to tell the user what to do are always an essential part of any program - even a simple five-liner.
There are more compact ways of writing certain expressions in the above - but in my experience, clarity ALWAYS trumps cleverness - and the compiler will typically optimize out any apparent redundancy. Thus - don't be afraid of extra parentheses to make sure you will get what you intended.
If you do need to dynamically increase the size of your array, look at realloc. It can be used in conjunction with malloc to create arrays of variable size. But it won't work if your initial array is declared as in the above code snippet.
Testing for a return value (of addScores, and thus effectively of scanf) >0 rather than !=0 catches the case where someone types ctrl-D ("EOF") to terminate input. Thanks #chux for the suggestion!

Resources