Variables retaining value after program is terminated, how to prevent? C - c

This is a program that asks the user to input Shipping information about selling bikes, pretty lame. At the end when it prints out the number of bikes order, and the total cost, the numbers get screwed up. The previously entered amounts seem to be sticking in the memory. How do I fix this? If that is not the problem I would not mind being told so :)
#include <stdio.h>
#include <math.h>
//structure
typedef struct
{char cust_name[25];
char add_one[20];
char add_two[20];
}ORDER;
ORDER order;
int main(void){
fflush(stdin);
system ( "clear" );
//initialize variables
double number_ordered = 0;
double price;
char bike;
char risky;
double m = 359.95;
double s = 279.95;
//inputs for order
printf("Enter Customer Information\n");
printf("Customer Name: ");
scanf(" %[^\n]s", &order.cust_name);
printf("\nEnter Street Address: ");
scanf(" %[^\n]s", &order.add_one);
printf("\nEnter City, State, and ZIP: ");
scanf(" %[^\n]s", &order.add_two);
printf("\nHow Many Bicycles Are Ordered: ");
scanf(" %d", &number_ordered);
printf("\nWhat Type Of Bike Is Ordered\n M Mountain Bike \n S Street Bike");
printf("\nChoose One (M or S): ");
scanf(" %c", &bike);
printf("\nIs The Customer Risky (Y/N): ");
scanf(" %c", &risky);
system ( "clear" );
//print order
printf("\n**********Shipping Instructions**********");
printf("\nTo: %s\n %s\n %s", order.cust_name, order.add_one, order.add_two);
if (bike == 'M' || bike == 'm')
printf("\n\nShip: %d Mountain Bikes", number_ordered);
else
printf("\n\nShip: %d Street Bikes", number_ordered);
if (bike == 'M' || bike == 'm')
price = number_ordered * m;
else
price = number_ordered * s;
if (risky == 'Y' || risky == 'y')
printf("\nBy Freight, COD %d\n", price);
else
printf("\nBy Freight, And Bill The Customer %d\n", price);
printf("*****************************************\n");
return 0;
}

You are printing number_ordered and price, which are doubles, using %d. %d is only for integer types. Use %lf to printf or scanf doubles.

The formats for both your scanf and your printf are wrong, so you're neither reading nor writing your values properly.

Related

Why does it skip my command in C ? please check it

#include <stdio.h>
int main()
{
int inpa, med, oper, day, total;
char agree;
printf(" Bach Mai Hospital");
printf("\n\nHello, please enter your fee and we will calculate\npayment based on your insurance\n");
printf("How many days have you been in the hospital ");
scanf("%d", &day);
printf("How much is your medicine fee ");
scanf("%d", &med);
printf("Have you undergone surgery (Yes or No)");
scanf("%s", &agree);
switch(agree){
case 'Y':
printf("Enter your surgery fee ");
scanf(" %d", &oper);
break;
case 'N':
oper = 0;
break;
};
printf("%s", agree);
inpa = day * 15000;
printf("Your total fee\n");
printf("Inpatient fee: %-10d x 15000 = %d\n", day, inpa);
printf("Medicine fee: %-10d\n", med);
printf("Surgery fee: %-10d\n", oper);
total = inpa + med + oper;
printf("\n\nYou pay: %d\n", total);
return 0;
}
It skips my command from when I enter &oper
printf("Enter your surgery fee ");
scanf(" %d", &oper);
And it is the result
Bach Mai Hospital
Hello, please enter your fee and we will calculate
payment based on your insurance
How many days have you been in the hospital 8
How much is your medicine fee 90000000
Have you undergone surgery (Yes or No)Yes
Enter your surgery fee 80000000
PS D:\Desktop\Cprogram>
I would be so thankful if someone explain for me why
previously I have trouble with the "agree" variable which I declare a char but it understands "agree" as int. Thank you
printf("%s") expects a null character(\0). Whenever you want to print a character, you should use %c rather than %s.So replace printf("%s", agree); with print("%c",agree);, then everything works well.
printf("%s", agree);
This line seems to cause issue because:
agree is a char variable in stack and hold only 1 byte
When printf with %s, it is expected that you provide an char array end with value 0 which is string terminator.
Because of this when you call printf("%s", agree);, it will trigger a call to a string at address 'Y' or in hex value 0x59. And the access to this address is illegal and will cause undefined behavior for your program.

How do I repeat entering data in a struct using C?

I'm new to C, and currently trying to practice on some simple codes, and I'm currently stuck with that next one.
After entering the first customer data, and repeat the code... View_customer function fails to show the saved data, and when I try to go to enter a second account data, it fails at the second entry.
#include<stdio.h>
#include<stdlib.h>
typedef struct cust{
char name[60];
int acc_no,age;
char address[60];
char citizenship[15];
double phone;
char acc_type[10];
} cust;
void new_account(int num);
void view_account(int num);
int main()
{
cust customers[10];
char answer;
int n;
int cutomer_number=1;
int cutomer_num2;
printf("Welcome To The program X: \n");
do{
printf("\n How can we serve you today? \n 1.Create a new account \n 2.Print an existing Account info \n ");
scanf("%d",&n);
if (n==1)
{
new_account(cutomer_number);
cutomer_number++;
}else {
printf("Please enter your Cust number: ");
scanf(" %d",&cutomer_num2);
view_account(cutomer_num2);
};
printf("\n Press Y to continue. Press any Key To Exit: ");
scanf(" %c",&answer);
}while (answer == 'Y' || answer == 'y');
return 0;
}
void view_account(int n)
{
cust customers[n];
printf("Your name is %s \n ", customers[n].name);
printf("Your age is %d \n", customers[n].age);
printf("Your address is %s \n", customers[n].address);
printf("Your citizenship is %s \n", customers[n].citizenship);
printf("Your phone number is %f \n", customers[n].phone);
printf("Your account type is %s \n", customers[n].acc_type);
};
void new_account(int n)
{
cust customers[n];
customers[n].acc_no = n;
printf("You are the customer number %d \n", customers[n].acc_no);
printf("Please, Enter your name: ");
scanf("%s", &customers[n].name);
printf("Please, Enter your age:");
scanf(" %d", &customers[n].age);
printf("Please, Enter your address: ");
scanf(" %s", &customers[n].address);
printf("Please, Enter your citizenship: ");
scanf(" %s", &customers[n].citizenship);
printf("Please, Enter your phone number: ");
scanf(" %f", &customers[n].phone);
printf("Please, Enter your account type: ");
scanf(" %s", &customers[n].acc_type);
}
>
Each of your three functions declares its own customers array variable, so each of them has their own memory for the customer data. Moreover, the array of new_account goes out of scope at the end of the function, so you can no longer safely access the data. Because of how C compilers typically work, the customer data is not immediately erased from memory, so your view_account function might still be able to read it, but that is what is called "undefined behavior". Which means it might work, or it might not.
Try to pass down the array from the main function to the other two functions in parameters. Or, to make things simpler at first, you could also turn the local customers variable of main into a global variable.
cust customers[10];
int main(int argc, char *argv[])
{
char answer;
int n;
int cutomer_number=1;
int cutomer_num2;
printf("Welcome To The program X: \n");
...
}
void view_account(int n) {
printf("Your name is %s \n ", customers[n].name);
...
}
void new_acccount(int n)
{
customers[n].acc_no = n;
...
}
Note that there are further issues in your code, like not checking the return value of scanf or overflowing the char arrays of the struct if you enter too many characters (missing bounds and length checking), or being able to enter more than 10 customers and accessing out of bounds of the customers array, or not using customers[0] (because your customer_number starts at 1, but array indices are 0-based). But I will not go into further details here to keep the answer focused.

My C program not taking full name as input and also printing absurd gender value

#include<stdio.h>
#include<stdlib.h>
char* genderfun(){
char *gender;
char g;
printf("\n >>> enter your gender (M/F/T): ");
//g = getc(stdin);
scanf(" %c",&g);
if(g == 'M'){
gender = "Male";
}else if(g == 'F'){
gender = "Female";
}else{
gender = "Transgender";
}
return gender;
}
float percentagecalculator(){
float math,physics,chemistry,english,other,percent;
printf("\n >>> Enter maths marks: ");
scanf("%f",&math);
printf("\n >>> Enter english marks: ");
scanf("%f",&english);
printf("\n >>> Enter physics marks: ");
scanf("%f",&physics);
printf("\n >>> Enter chemistry marks: ");
scanf("%f",&chemistry);
printf("\n >>> Enter additional subject marks: ");
scanf("%f",&other);
percent = ((math+english+physics+chemistry+other)/500)*100;
return percent;
}
void main(){
char *name;
char* genders;
int age,count;
float percent;
printf(">>> Enter your name: ");
scanf(" %c",&name);
//fflush(stdin);
printf("\n >>> Enter your age: ");
scanf("%d",&age);
genders = genderfun();
percent = percentagecalculator();
if(percent < 33){
printf("\n name : %c \n age : %d \n gender : %c \n Percentage : %f \n Status : Failed",name,age,genders,percent);
}else if(percent >= 33){
printf("\n name : %c \n age : %d \n gender : %c \n Percentage : %f \n Status : Passed",name,age,genders,percent);
}else{
printf("\n Error");
}
}
My code is not taking a name more than one character as input and if I try that it skips everything and programs ends and also the gender is not being returned but instead it prints very absurd values in console. Please help me fix this bug.
Well, I've been reading your code and there are several problems. Here are the ones that I've found out:
Return type of 'main' is not 'int'.
In main: Unused variable 'count'
Missing spacing and camel notation for function
You're assuming to read string, but you are actually reading a char (e.g. the name, the creation of gender string, and so on).
You're trying to insert a string, but reading a char, you pollute all your input buffer.
You're using fflush(...). Please check here why you shouldn't use it: Using fflush(stdin)
In order to use strings (or array of char) while reading dynamically names and assigning chars to an array of char, you need dynamic memory or at least VLA (in the following code, you will find the implementation with Dynamic Memory).
In the 'percentage calculator' function you are assuming to take multiple values for each subject. Actually, you are taking only one mark for each subject.
You are going wrong while reading a string. Here's how to properly do that:
How to read string from keyboard using C?
You are trying to print a char instead of a string in the final print.
Please do a better naming of your variables and your functions.
I'm gonna attach here a working code for your question:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define stringSize 256
char * readGender() {
fseek(stdin, 0, SEEK_END);
char * gender = (char *) malloc(stringSize);
char g;
if (!gender) exit(EXIT_FAILURE);
printf("\n >>> Enter your gender (M/F/T): ");
g = getchar();
if (g == 'M') {
strcpy(gender, "Male");
}else if(g == 'F') {
strcpy(gender, "Female");
}else {
strcpy(gender, "Transgender");
}
gender = (char *) realloc(gender, strlen(gender) + 1);
if (!gender) exit(EXIT_FAILURE);
return gender;
}
float percentageCalculator() {
float math, physics, chemistry, english, other, percent;
printf("\n >>> Enter math mark: ");
scanf("%f", &math);
printf("\n >>> Enter english mark: ");
scanf("%f", &english);
printf("\n >>> Enter physics mark: ");
scanf("%f", &physics);
printf("\n >>> Enter chemistry mark: ");
scanf("%f", &chemistry);
printf("\n >>> Enter additional subject mark: ");
scanf("%f", &other);
percent = ((math + english + physics + chemistry + other) / 500) * 100;
return percent;
}
int main() {
char * gender;
int age;
float percentage;
char *name = (char *) malloc(stringSize);
if (!name) exit(EXIT_FAILURE);
printf(">>> Enter your name: ");
fgets(name, sizeof(stringSize - 1), stdin);
name = (char *) realloc(name, strlen(name));
if (!name) exit(EXIT_FAILURE);
fseek(stdin, 0, SEEK_END);
printf("\n >>> Enter your age: ");
scanf("%d", &age);
gender = readGender();
percentage = percentageCalculator();
if (percentage < 33) {
printf("\n name : %s \n age : %d \n gender : %s \n Percentage : %f \n Status : Failed\n", name, age, gender, percentage);
} else if (percentage >= 33) {
printf("\n name : %s \n age : %d \n gender : %s \n Percentage : %f \n Status : Passed\n", name, age, gender, percentage);
} else {
printf("\n Error");
}
return 0;
}
Note that I've used fseek(...) as suggested here: How to clear input buffer in C? in order to read correctly char and integers together.
fseek(...) works on some systems; if not, then it is not surprising as nothing guarantees that it will work when standard input is an interactive device (or a non-seekable device like a pipe or a socket or a FIFO, to name but a few other ways in which it can fail).
If you need that it has to be portable, then check the link that I've placed before. Hope that it was helpful.
Next steps:
Adding user input error handling
Use a switch in 'readGender(...)' instead of the final triple if
Cheers, Denny
#include<stdio.h>
#include<stdlib.h>
/*
# Mistakes to avoid in future
1. use fgets(name_of_inputVariable,size,stdin) instead of scanf
2. use %s for strings rather than %c
3. use *name_of_variable for the strings
4. use fflush(stdin) only when program is skipping a certain step.
5. use switch statements for the character stuff.
*/
char* getGender(){
char *gender,g;
printf(">>> enter a gender (m/f/t): ");
scanf("%c",&g);
switch(g){
case 'm':
gender = "Male";
break;
case 'f':
gender = "Female";
break;
case 't':
gender = "Transgender";
break;
default:
gender = "prefer not to say";
}
return gender;
}
float percentageCalculator(){
float math,physics,chemistry,english,other,percent;
printf("\n >>> Enter maths marks: ");
scanf("%f",&math);
printf("\n >>> Enter english marks: ");
scanf("%f",&english);
printf("\n >>> Enter physics marks: ");
scanf("%f",&physics);
printf("\n >>> Enter chemistry marks: ");
scanf("%f",&chemistry);
printf("\n >>> Enter additional subject marks: ");
scanf("%f",&other);
percent = ((math+english+physics+chemistry+other)/500)*100;
return percent;
}
void main(){
char name[35];
char *gender;
int age,count;
float percent;
printf("\n >>> Enter your name: ");
fgets(name,35,stdin); //fgets is way better than scanf. you can use exact value 35
//scanf("%34s",&name); // scanf is a little buggy. you need to add one value less to prefent buffer overflow i.e. "%34s"
//fflush(stdin); // fflush do solved problem as it took entire name but only printed first character in output. It's fixed via fgets now.
printf("\n >>> Enter your age: ");
scanf("%d",&age);
fflush(stdin); // It was skipping gender ask step, so fflush fixed it by cleaning the overflow buffer. (fixed)
gender = getGender(); // getGender have some problem. It prints very absurd values in output console. (fixed)
percent = percentageCalculator(); // percentage calculator is working 100% fine. I got my accurate percentage and status lol ;)
if(percent < 33){
printf(" name : %s \n age : %d \n gender : %s \n Percentage : %f \n Status : Failed",name,age,gender,percent);
}else if(percent >= 33){
printf(" name : %s \n age : %d \n gender : %s \n Percentage : %f \n Status : Passed",name,age,gender,percent);
}else{
printf("\n Error");
}
}
Here I have finally fixed all issues in my code and now my program is working correctly. Thanks for some ideas stackoverflow community.

Integers don't show when written into .dat file in c

I am trying to write some records (patient info) into a .dat file using c. The patient info contains the National ID no., name, gender and the telephone no.
Here's my code:
#include<stdio.h>
int main(void)
{
char order = 'y';
int nic = 0; // NIC no.
char name[] = "xxx"; // name
char gender = 'x'; // Patients' gender
int tel_no = 0; // telephone no.
FILE *fp;
fp = fopen("patientdetails.dat", "w"); // Creat patientdetails file
if (fp == NULL)
{
printf("Cannot open file\n");
return -1;
}
else
{
printf("Do you want to enter a record (y/n): ");
scanf("%c", &order);
while (order == 'y' || order == 'Y')
{
printf("Enter nic no.: ");
scanf("%d", &nic);
printf("Enter name: ");
scanf("%s", name);
printf("Enter gender (m/f): ");
scanf(" %c", &gender);
printf("Enter tel no.: ");
scanf("%d", &tel_no);
fprintf(fp, "%d %s %c %d\n", nic, name, gender, tel_no);
printf("Do you want to enter a record (y/n): ");
scanf(" %c", &order);
}
fclose(fp);
}
return 0;
}
However when I enter the following info into my .dat file in the terminal:
Do you want to enter a record (y/n): y
Enter nic no.: 200007102766
Enter name: Timothy
Enter gender (m/f): m
Enter tel no.: 0779428897
Do you want to enter a record (y/n): n
There is an error in the integers, namely nic no. and telephone no.
Additionally I made another program to read the file, the error in the integers still seem to show up.
Errors in the .dat file:
7956596 Timothy m 779428897
I can't seem to figure out how to correct the integer errors,
where 20007102766 is shown as 7956596
and 0779428897 is shown as 779428897.
Any help is appreciated!
Your variable byte size is larger than a int, so you should use bigger variable type.
In your example, you can use long type for nic and tel_no veriables.
Also you should use %ld in format, otherwise it gives you warning.
char order = 'y';
long nic = 0; // NIC no.
char name[] = "xxx"; // name
char gender = 'x'; // Patients' gender
long tel_no = 0; // telephone no.
And while formating
printf("Enter nic no.: ");
scanf("%ld", &nic);
printf("Enter tel no.: ");
scanf("%ld", &tel_no);
fprintf(fp, "%ld %s %c %ld\n", nic, name, gender, tel_no);

Creating a gradebook program in C

I'm working on a program that will keep track of grades entered. The program should ask if the user is finished inputting grades. If the the user is not finished, the user will continue to enter grades. If the user is finished, program will print the grades. Every time I run the program, it crashes.
Here's what I got.
#include <stdio.h>
int main (){
int i = 0;
float gradeBook;
char ans, y, Y, n, N;
printf("Please enter grade %d: ", i + 1);
scanf("%.2f", &gradeBook);
printf("\nDo you have more grades to enter? [Y or N] ");
scanf("%c", ans);
while(ans == 'y' || ans == 'Y'){
printf("Please enter the next grade %d: ", i + 1);
scanf("%i", &gradeBook);
printf("\nDo you have more grades to enter? ");
scanf("%c", ans);
}
printf("You have entered %d grades", i);
printf("The grades you have entered are %.2f ", gradeBook);
return 0;
}
You should use arrays for problems like this. Here is what I did:
#include <stdio.h>
int main (){
int i = 0, j;
float gradeBook[20];
char ans;
printf("Please enter grade %d: ", i + 1);
scanf("%f", &gradeBook[0]);
printf("\nDo you have more grades to enter? [Y or N] \n");
scanf(" %c", &ans);
while (ans == 'y' || ans == 'Y') {
printf("Please enter the next grade: \n");
i += 1;
scanf("%f", &gradeBook[i]);
printf("\nDo you have more grades to enter? \n");
scanf(" %c", &ans);
}
printf("You have entered %d grades\n", i+1);
printf("The grades you have entered are: \n");
for (j=0; j<=i; j++)
printf("%.2f ", gradeBook[j]);
printf("\n\n");
return 0;
}
Your program crashes because you are missing the & in ans in your scanf. Without the &, the scanf treats the value in "ans" as an address, and will try to access it, thus seg fault.
PS: In each iteration you are overwriting the value in "gradeBook", if you want to print a set of values, you should use an array.

Resources