Gradebook, array not saving - c

So I'm trying to make a grade book that does everything displayMenu() says. But i cant even get the student ID to save when i go to view the grades. Please Help.
Everything is initialized here
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define PAUSE system("pause")
#define CLS system("cls")
#define EXAMS 100
#define STUDENT 4
void displayArray(float grades[STUDENT][EXAMS]);
void newStudent(float grades[STUDENT][EXAMS]);
void displayStudentAverage(float grades[STUDENT][EXAMS]);
int main() {
float grades[STUDENT][EXAMS];
This is everything the program should do
displayMenu(grades, 0 );
} // end of main;
int displayMenu(float grades[STUDENT][EXAMS]) {
printf("\t \t MENU \t \t");
printf("Enter Corresponding Number\n");
printf("1.Enter New Student\n");
printf("2.Change Existing Grades\n");
printf("3.View All Grades\n");
printf("4.View Average Score Per Student\n");
printf("5.View Average Score Per Exam\n");
printf("6.View Average Score For The class\n");
printf("7.CLEAR GRADEBOOK\n");
printf("8. Save Gradebook\n");
printf("8.Exit\n");
int choice = 0;
scanf("%d", &choice);
switch (choice) {
case 1:
newStudent(grades, 0);
CLS;
displayMenu(grades,0);
break;
case 2:
break;
case 3: displayArray(grades, 0);
CLS;
displayMenu(grades,0);
break;
case 4:
displayStudentAverage(grades, 0);
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
exit(0);
break;
case 9:
exit(0);
break;
default: printf("You Have entered an incorrect number");
PAUSE;
}
}
This is what displays the grades
void displayArray(float grades[STUDENT][EXAMS]) {
printf("%.1f\t", grades[STUDENT][EXAMS]);
}
I'm trying to add the values to the array here
void newStudent(float grades[STUDENT][EXAMS]) {
float addgrade;
printf("Please Enter Student ID: ");
scanf("%f", &grades[STUDENT][EXAMS]);
printf("Enter four exam grades, use comma to split grades");
scanf("%f", addgrade);
grades[STUDENT][EXAMS] += addgrade;
PAUSE;
CLS;
}
void displayStudentAverage(float grades[STUDENT][EXAMS]) {
int sum, loop;
float avg;
sum = avg = 0;
for (loop = 0; loop < 10; loop++) {
sum = sum + grades[loop];
}
avg = (float)sum / loop;
printf("Average of array values is %.2f", avg);
}

First of all, it's always good check the compiler warnings to get some hints to possible bugs...
Here's a list of problems in the code:
no header files included
displayMenu prototype is missing
the grades array is used with inconsistent types (float/int)
with grades[STUDENT][EXAMS] the grades array is accessed out of bounds (for example if you define an array of size 5 you can only access position 0 to 4)
the return type of main needs to be int
the function newStudent has return type void but the code tries to return something with return &grades[STUDENT][EXAMS];
Apart from that, the code should work...

Related

C Program, Array inside a case in continuous Switch Menu loop

My array inside case 4 in looping Switch Menu doesn't print/display the value of the last array when the user input goes beyond array[4].
I tried to take the case 4 out and make it a single program to check if it doesn't really work on its own but it works fine, but when I put it back into the Switch, same issue again. I thought that maybe the initialization part is the problem. Help
`
#include <stdio.h>
int main ()
{
char first[20],last[20];
float math,eng,sci,avg;
int a,b,c,d,diff,array[diff],e,i,input;
do{
printf("\nMAIN MENU\n");
printf("[1] Basic Input Output\n[2] Conditional Statement\n[3] Looping Construct\n[4] Array\n[5] About\n[6] Exit");
printf("\n\nChoose: ");
scanf("%d",&input);
printf("\n");
switch (input)
{
case 1:
printf("\nEnter your given name:");
scanf("%s",first);
printf("Enter your surname:");
scanf("%s",last);
printf("\nHello %s %s!\n",first,last);
break;
case 2:
printf("\nEnter your grade in Math:");
scanf("%f",&math);
printf("\nEnter your grade in Science:");
scanf("%f",&sci);
printf("\nEnter your grade in English:");
scanf("%f",&eng);
avg=(math+eng+sci)/3;
if(math>eng&&sci)
{
printf("\nHighest grade is in: Math");
}
if(eng>math&&sci)
{
printf("\nHighest grade is in: English");
}
if(sci>eng&&math)
{
printf("\nHighest grade is in: Science");
}
if(math==eng)
{
printf("\n--Math and English tied grades--");
}
if(math==sci)
{
printf("\n--Math and Science tied grades--");
}
if(eng==sci)
{
printf("\n--Science and English tied grades--");
}
printf("\nYour average in 3 subjects:%f\n",avg);
break;
case 3:
printf("Enter beginning number: ");
scanf("%d",&b);
printf("Enter ending number: ");
scanf("%d",&c);
printf("\nCounting from %d to %d\n",b,c);
while(b<=c)
{
printf("%d ",b);
b++;
}
printf("\n");
break;
case 4:
printf("Enter Starting Series of Numbers: ");
scanf("%d",&a);
printf("Enter Ending Series of Numbers: ");
scanf("%d",&d);
diff=(d-a);
array[diff]=d;
printf("Select Array Value to Display: 0 to %d: ",diff);
scanf("%d",&e);
for(i=0;i<=diff;i++)
{
array[i]=a;
if(i==e)
{
printf("%d\n",array[i]);
}
a++;
}
break;
case 5:
printf("Abouts\n");
break;
case 6:
printf("Thank you!");
break;
}
}while(input != 6);
return 0;
}
`
This should be a comment, but I donĀ“t have enough reputation yet.
As Gerhardh said, the problem is that you use diff before being initialized (which causes undefined behaviour)
As you said, if you move the initialization of array inside the case 4: after diff being set the program should work as intended. If you want to keep it before the switch, try using int* and malloc/free inside the case 4: (and add #include <stdlib.h>) Anyway, you should check diff as positive value before using it to set the size of array
About optimizing the code, you can skip the line array[diff]=d; because you are setting the same value inside the for loop. And you can remove the line a++; if you changes array[i]=a; -> array[i]=a+i;

Trying to find duplicates in a Struct Array in C

I've attempted to find if the user has inputted a product id value that's a duplicate and if so, it just tells them that it's a duplicate value and then returns to the menu in my switch statement.
The actual result i get, is that after "productsfilled == 0", it won't utilise the For Loops to check for the duplicates and productsfilled will remain at 1. I've looked online and this way of finding duplicates tends to work and i have used it previously in my code, so I don't think that could be the issue.
Here's my code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <conio.h>
int productsfilled;
struct ProductData{
int product_id;
char product_name[120];
int price;
};
int quiz_5(){
char ch;
int size, input = 0;
struct ProductData products[20];
while(1){
printf("\nWelcome To The Super Mall's Product List. Please Select An Option:\n1. Add Product\n2. Display Product\n3. Delete Product\n");
fflush(stdin);
switch(getchar()){
case '1':
printf("\nPlease Enter Product ID:");
scanf("%d",&products[productsfilled].product_id);
printf("\nPlease Enter Product Name:");
scanf("%s",&products[productsfilled].product_name);
printf("\nPlease Enter Product Price:");
scanf("%d",&products[productsfilled].price);
printf("Productsfilled: %d",productsfilled);
if(productsfilled == 0){
productsfilled = 1;
break;
}
for(int i = 0; i < productsfilled;i++){
for (int j = i + 1; j < productsfilled;j++){
if(products[i].product_id == products[j].product_id){
printf("\nPlease Use Different Product ID");
break;
}else{
printf("test");
productsfilled += 1;
break;
}
}
}
break;
case '2':
while(1){
for(int i = 0;i < productsfilled;i++){
printf("Product ID: %d Product Name: %s Product Price: %d\n",products[i].product_id,products[i].product_name,products[i].price);
}
printf("Please Press Enter To Continue");
fflush(stdin);
if(getchar() == '\n'){
break;
}
}
case '3':
break;
case '\n':
break;
default:
printf("Please Select An Option:\n1. Add Product\n2. Display Product\n3. Delete Product: ");
}
}
}
int main() {
int input = 1;
printf("Welcome to my assignment. Which quiz do you want to run (please input the number of the quiz e.g. for quiz 1, type 1): \n-Quiz 1\n-Quiz 2\n-Quiz 3\n-Quiz 4\n-Quiz 5\n-Quiz 6\n-Quiz 7\n");
while(input == 1){
fflush(stdin);
switch(getchar()){
case '5':
quiz_5();
break;
case '\n':
printf("Welcome to my assignment. Which quiz do you want to run (please input the number of the quiz e.g. for quiz 1, type 1): \n-Quiz 1\n-Quiz 2\n-Quiz 3\n-Quiz 4\n-Quiz 5\n-Quiz 6\n-Quiz 7\n");
getchar();
default:
printf("Invalid Input\n");
} }
return 0;
}
The problem is that you don't increment productsfilled before you enter the loop...therefore, productsfilled is always 1 less than the actual length of your array which means that you don't compare all elements in the array.
Try your program on 2 inputs, both with the same ID. You'll see that you don't compare anything.
You are wrong when using scanf for string input:
scanf("%s",&products[productsfilled].product_name);
You should not use &, you should use as below:
scanf("%119s",products[productsfilled].product_name);
OT, in main function:
switch(getchar()){
case '5':
...
Because getchar() will return int value, so if you want to access to quiz_5, you have to type 35 (ANSCI code) instead of type 5 when you run your program.
char a = '5';
similar to:
int a = 35;

Why is the loop not stopping?

#include <stdio.h>
#include <stdlib.h>
#define NEWGEAR 15.0
#define USEDGEAR 5.0
int main() {
int type;
int num_items;
float total;
printf("Welcome to the market\n");
printf("What would you like to do\n");
printf("\t1-Buy New Gear\n");
printf("\t2-Buy used gear\n");
printf("\t3-Quit\n");
scanf("%d", &type);
while (type != 3) {
switch (type) {
case 1:
printf("How many new items would you like?\n");
scanf("%d", &num_items);
total = num_items * 15.0;
break;
This is where the code keeps on asking how many new items would you like?
case 2:
printf("How many old items would you like?\n");
scanf("%d", &num_items);
total = num_items * USEDGEAR;
break;
This is where the code keeps on asking how many old items would you like?
case 3:
break;
default:
printf("Not a valid option\n");
break;
}
}
printf("Your total cost is %f\n",total);
return 0;
}
Both my choices are looping
You never update the type variable to 3, so the while loop never terminates. Although you do have a break statement, it is affecting the switch and not the while loop that surrounds it.
I think this will handle what you want to achieve.
#include <stdio.h>
#include <stdlib.h>
#define NEWGEAR 15.0
#define USEDGEAR 5.0
int main() {
int type = 0;
int num_items;
float total;
printf("Welcome to the market\n");
printf("What would you like to do\n");
printf("\t1-Buy New Gear\n");
printf("\t2-Buy used gear\n");
printf("\t3-Quit\n");
while (type != 3) {
printf("Enter an option: ");
scanf("%d", &type);
if(type == 3)
break;
switch (type) {
case 1:
printf("How many new items would you like?\n");
scanf("%d", &num_items);
total = num_items * 15.0;
break;
case 2:
printf("How many old items would you like?\n");
scanf("%d", &num_items);
total = num_items * USEDGEAR;
break;
default:
printf("Not a valid option\n");
break;
}
}
printf("Your total cost is %f\n",total);
return 0;
}
Basically, after your user finished doing cases 1-2 or default, your program would prompt your user for an option again if he wants to quit or perform another case 1 or 2 operation.
Your loop logic is flawed:
you should move the prompt code inside the loop.
you should update total for each answer.
you should test if scanf() is successful at converting user input.
Here is a modified version:
#include <stdio.h>
#define NEWGEAR 15.0
#define USEDGEAR 5.0
int main() {
int type;
int num_items;
double total = 0;
printf("Welcome to the market\n");
for (;;) {
printf("What would you like to do\n");
printf("\t1-Buy New Gear\n");
printf("\t2-Buy used gear\n");
printf("\t3-Quit\n");
if (scanf("%d", &type) != 1 || type == 3)
break;
switch (type) {
case 1:
printf("How many new items would you like?\n");
if (scanf("%d", &num_items) == 1)
total += num_items * 15.0;
break;
case 2:
printf("How many old items would you like?\n");
if (scanf("%d", &num_items) == 1)
total += num_items * USEDGEAR;
break;
default:
printf("Not a valid option\n");
break;
}
}
printf("Your total cost is %f\n", total);
return 0;
}

My do while loop is not looping correctly

I might be giving more than enough but long story short I am working on an ATM machine program and I am trying to put the "switch" statement in the main function inside a loop so the user can get more transactions.
I am running into a problem where I would deposit 100 but then when I check the balance it is still at 0. I know everything else works fine but that loop is killing me, I would appreciate any help!
Don't mind all of the extra stuff it is just there to give an idea on what i am working on
int main ()
{
char option;
float balance ;
int count = 1;
option = displayMenu();
do
{
switch (option)
{
case 'D':
getDeposit(balance);
main();
count++;
break;
case 'W':
getWithdrawal(balance);
main();
count++;
break;
case 'B':
displayBalance(balance);
main();
count++;
break;
case 'Q':
printf("Thank you!");
break;
main();
}
} while ( count <= 5);
return 0;
}
char displayMenu()
{
char option;
printf("\n Welcome to HFC Federal Credit Union \n");
printf("\n Please select from the following menu: \n ");
printf("\n D: Make a deposit \n ");
printf("\n W: Make a withdrawal \n ");
printf("\n B: Check your account balance \n ");
printf("\n Q: To quit \n ");
scanf("\n%c" , &option);
return option;
}
float getDeposit(float balance)
{
float deposit;
printf("\n Please enter the amount you want to deposit! ");
scanf("%f" , &deposit);
balance += deposit;
return balance;
}
float getWithdrawal(float balance)
{
float withdrawal;
printf("\n Please enter the amount you want to withdraw! ");
scanf("%f" , &withdrawal);
balance -= withdrawal;
return balance;
}
void displayBalance(float balance)
{
printf("\n Your current balance is %f " , balance);
}
You're recursively calling main() on every iteration of the loop. Just remove this call, and you should be good to go.
You'll also need to assign the return values of your functions to balance, otherwise they won't be able to affect its value.
There are a number of issues with this code... Here are my main pointers (but not all of them, I'm just answering the question):
You're calling main over and over again, for simplicity, you could consider this as restarting the application every time (except for stack issues, that I'm ignoring and other nasty side effects).
You didn't initialize the balance (and friends) variables. They might contain "junk" data.
You're ignoring the return values from the functions you use. If you're not using pointer, you should use assignment.
Your menu printing function is out of the loop... I doubt if that's what you wanted.
Here's a quick dirty fix (untested):
int main() {
char option;
float balance = 0;
int count = 1;
do {
option = displayMenu(); // moved into the loop.
switch (option) {
case 'D':
balance = getDeposit(balance);
count++;
break;
case 'W':
balance = getWithdrawal(balance);
count++;
break;
case 'B':
balance = displayBalance(balance);
count++;
break;
case 'Q':
printf("Thank you!");
break;
}
} while (count <= 5);
return 0;
}
char displayMenu(void) {
char option;
printf("\n Welcome to HFC Federal Credit Union \n");
printf("\n Please select from the following menu: \n ");
printf("\n D: Make a deposit \n ");
printf("\n W: Make a withdrawal \n ");
printf("\n B: Check your account balance \n ");
printf("\n Q: To quit \n ");
scanf("\n%c", &option);
return option;
}
float getDeposit(float balance) {
float deposit;
printf("\n Please enter the amount you want to deposit! ");
scanf("%f", &deposit);
balance += deposit;
return balance;
}
float getWithdrawal(float balance) {
float withdrawal;
printf("\n Please enter the amount you want to withdraw! ");
scanf("%f", &withdrawal);
balance -= withdrawal;
return balance;
}
void displayBalance(float balance) {
printf("\n Your current balance is %f ", balance);
}
Good Luck!
I think the main problem is the update of the switch control variable outside the loop.
Reacting to "Q" with ending is somewhat necessary... then only allowing 5 becomes unneeded.
I fixed several other things, too; and provided comments on them.
And I improved testability a little (5->6). I kept the counting, just extended to 6, in order to allow a complete test "D 100 , B, W 50, B ,Q".
Nice design by the way, to return the balance from the functions, instead of using pointers or global variable. But you need to use the return value instead of ignoring it.
/* include necessary headers, do not skip this when making your MCVE */
#include <stdio.h>
/* prototypes of your functions,
necessary to avoid the "immplicitly declared" warnigns
when compiling "gcc -Wall -Wextra"; which you should
*/
char displayMenu(void);
float getDeposit(float balance);
float getWithdrawal(float balance);
void displayBalance(float balance);
/* slightly better header of main, with "void" */
int main (void)
{
char option;
float balance=0.0; /* initialise your main variable */
int count = 1;
/* your very important update of the switch control variable has been moved ... */
do
{
option = displayMenu(); /* ...here */
/* If you do not update your switch variable inside the loop,
then it will forever think about the very first command,
this explains most of your problem.
*/
switch (option)
{
case 'D':
balance=getDeposit(balance); /* update balance */
/* removed the recursive call to main(),
it is not needed as a solution to the problem that the program
always uses the first command (when updating inside the loop)
and otherwise just makes everything much more complicated and
risky.
*/
count++;
break;
case 'W':
balance=getWithdrawal(balance); /* update balance */
count++;
break;
case 'B':
displayBalance(balance);
count++;
break;
case 'Q':
printf("Thank you!");
/* adding a way to get out of the loop,
using a magic value for the count,
this is a mehtod frowned upon by most,
but it minimises the changes needed to your
own coding attempt.
*/
count=0;
break;
}
} while ( (count <= 6)&&(count>0) ); /* additionally check for the magic "Q" value
check against count<=6, to allow testing D,B,W,B,Q */
return 0;
}
/* use explicitly empty parameter list for functions */
char displayMenu(void)
{
char option;
printf("\n Welcome to HFC Federal Credit Union \n");
printf("\n Please select from the following menu: \n ");
printf("\n D: Make a deposit \n ");
printf("\n W: Make a withdrawal \n ");
printf("\n B: Check your account balance \n ");
printf("\n Q: To quit \n ");
scanf("\n%c" , &option);
return option;
}
float getDeposit(float balance)
{
float deposit;
printf("\n Please enter the amount you want to deposit! ");
scanf("%f" , &deposit);
balance += deposit;
return balance;
}
float getWithdrawal(float balance)
{
float withdrawal;
printf("\n Please enter the amount you want to withdraw! ");
scanf("%f" , &withdrawal);
balance -= withdrawal;
return balance;
}
void displayBalance(float balance)
{
printf("\n Your current balance is %f " , balance);
}
you haven't changed the variable in main().
you can change the loop to this:
do
{
switch (option)
{
case 'D':
balance = getDeposit(balance);
count++;
break;
case 'W':
balance = getWithdrawal(balance);
count++;
break;
case 'B':
displayBalance(balance);
count++;
break;
case 'Q':
printf("Thank you!");
break;
}
} while (count <= 5);

Calling a function in printf in C?

I am a beginner in C programming.
I was writing a simple program to calculate average.
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int main()
{
int n, s = 0, num, i;
float avg;
printf("Enter value of total no\n");
scanf("%d", &n);
for (i=1; i<=n; i++)
{
void pri(int i){
switch(i){
case 1:
printf("st");
break;
case 2:
printf("nd");
break;
case 3:
printf("rd");
break;
default:
printf("th");
break;
}
}
printf("Enter %d pri(i) number\n", i);
scanf("%d", &num);
s += num;
}
avg = s / n;
printf("The average is %f",avg);
return 0;
}
But pri(i) is not working as I expected. But later I found another way to do this, so here is the second version of this code:
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
int main()
{
int n, s = 0, num, i;
float avg;
printf("Enter value of total no\n");
scanf("%d",&n);
for (i=1; i<=n; i++)
{
void pri(int i){
switch(i){
case 1:
printf("enter 1st number\n");
break;
case 2:
printf("enter 2nd number\n");
break;
case 3:
printf("enter 3rd number\n");
break;
default:
printf("enter %dth number\n",i);
break;
}
}
pri(i);
scanf("%d", &num);
s += num;
}
avg = s / n;
printf("the average is %f",avg);
return 0;
}
I want to get the results of this second piece of code from the first version.
Can I call functions in printf which are defined somewhere in program?
You cannot tell printf() to call another function in the middle of its execution. printf() expects to receive a formatting string and arguments to replace parts of this string. What you're trying to do (embed a function call in the formatting string) is not possible for a number of reasons.
What you can do is return the string instead of printing it and use it as argument.
const char *pri(int i) {
switch(i) {
case 1:
return "st";
case 2:
return "nd";
case 3:
return "rd";
default:
return "th";
}
}
printf("enter %d%s number\n", i, pri(i));
C doesn't support nested functions (function defined inside another function). Your code works because your compiler adds support for such functions as an extension. In general, you should probably avoid nesting functions.

Resources