I'm new to C and I am trying to write a program that will let you enter up to 100 people's age and salary. The program at first will print some sentences to introduce (the display function) and then ask you whether you want to continue or not (yes_no function). After you enter a person's information, the program will also ask if you would like to continue to enter the next person's information or not. If you would like to continue, you will need to enter 1 and 0 for no/exit. When I compile and run the code, I found a problem and i could not figure out why!
The problem is that if you choose 0 (which means no/exit) after entering one's information, the program does not exit. It instead just asks the next person's information. But when I choose 0 right from the beginning, it just exits like usual. Why?
#include<stdio.h>
#define max 100
#define yes 1
#define no 0
int display(void);
int yes_no(void);
void get_data(void);
int date[max],month[max],year[max];
int cont;
int salary;
int main(){
cont=display();
if (cont==yes){
get_data();
}
return 0;
}
int display(void){
printf("This program will let you enter ");
printf("the age and salary of up to 100 people ");
cont=yes_no();
return cont;
}
int yes_no(void){
int i=0;
printf("\nDo you want to continue? Enter 1 for Yes and 0 for No\n");
scanf("%d", &i);
while(i<0 || i>1){
printf("Invalid value.Please enter again\n");
scanf("%d", &i);
}
if(i==1){
return (yes);
}else return (no);
}
void get_data(void){
int i=0;
for(i=0;i<max;i++){
printf("Enter information for people %d\n", i+1);
printf("Enter birthday\n");
do{
printf("Enter date\n");
scanf("%d", &date[i]);
}while( 0>date[i] || 31<date[i] );
do{
printf("Enter month\n");
scanf("%d", &month[i]);
}while( 0>month[i] || 12<month[i]);
do{
printf("Enter year\n");
scanf("%d", &year[i]);
}while( 1900>year[i] || 2016<year[i]);
printf("Enter salary\n");
scanf("%d", &salary);
cont=yes_no();
}
}
void get_data(void){
int i=0;
for(i=0;i<max;i++){
printf("Enter information for people %d\n", i+1);
printf("Enter birthday\n");
do{
printf("Enter date\n");
scanf("%d", &date[i]);
}while( 0>date[i] || 31<date[i] );
do{
printf("Enter month\n");
scanf("%d", &month[i]);
}while( 0>month[i] || 12<month[i]);
do{
printf("Enter year\n");
scanf("%d", &year[i]);
}while( 1900>year[i] || 2016<year[i]);
printf("Enter salary\n");
scanf("%d", &salary);
cont=yes_no(); // <== The Problem lies here
}
}
You ask the user if wants to continue but you never check the return value of yes_no()
Just add this after this line and it should work like a charm:
if (cont == no)
return;
As others have mentioned, there are still some things you can do to "improve" your code.
defines should be capitalized so #define YES 1 would stick to this convention.
And you shouldn't use global variables. These are bad programming style. Simply pass the things you need in other functions as a parameter and if you need the manipulated value later on past them as a pointer.
Also the formatting could be improved (however this is a mostly opinion based topic ;) )
In C you usually have an extra line for each curly bracket.
void get_data(void)
{
...
}
//instead of
void get_data(void){
...
}
Also the blanks after the do-while-loop should look more like so:
do
{
...
} while(1900 > year[i]); //here the curly bracket is ok that way
And operators should have a blank on both sides:
printf("Enter information for people %d\n", i + 1);
// instead of this
printf("Enter information for people %d\n", i+1);
This is all I've seen up to now.
Related
This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Why is the gets function so dangerous that it should not be used?
(13 answers)
Closed 10 months ago.
#include <stdio.h>
void input(void);
void avgSalary(void);
struct Person{
char name[15];
int age;
float salary;
};
struct Person person[10];
int main(){
int choice, avg;
char cont;
do{
printf("1. Input person record \n2. Average salary\n");
printf("\nPlease enter selection: ");
scanf("%d", &choice);
if (choice == 1){
input();
}
else if (choice == 2){
avgSalary();
}
else{
printf("Error");
};
printf("\nContinue?: ");
scanf("%c", &cont);
printf("\n");
}while(toupper(cont)=='Y');
}
void input(){
int x;
getchar();
for (x=0;x<10;x++){
printf("Person %d\n", x+1);
printf("Name: ");
gets(person[x].name);
printf("Age: ");
scanf("%d", &person[x].age);
printf("Salary: ");
scanf("%f", &person[x].salary);
};
}
void avgSalary(){
int x, sum=0;
float avg=0;
for (x=0;x<10;x++){
sum += person[x].salary;
};
avg = sum/10;
printf("The average salary of %d person is %.2f\n", x, avg);
}
For the output, It asks for person's info and another is the average salary. We select 1 then after entering the first person's name, age and salary, I couldn't enter the next person's name all the way until the 10th person. Why is this happening?
Try replacing gets(person[x].name); with scanf .You could try scanf("%s",person[x].name); . Or you could probably (not recommended) add a getchar() at the end of your loop,after the last scanf call. In your first run through the loop,you are getting the behavior you want because you use the getchar() that is being called before the loop.
Edit:
Keep in mind that,using scanf you can't take an input containing a full name. If you want to do that,you can either use a seperate array for the last name in your Struct.Or else you can just probably get away with using getchar() and gets.
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.
Whenever I run this I got something like ' 196875307' as the total, could
someone tell me whats wrong with it.Here I uploaded the whole code.It says my post is mostly code and to add more details,So forgive me for typing these unnecessory things XD
#include <stdio.h>
int room;
char name[20];
int i;
void main()
{
int answr,fc[6],z=0,tot;
char ans;
char food[8][30]={"Bread","Noodles","Salad","Popcorn","Chocolate ice
cream","Vanilla ice cream","Cold Coffee","Milk Shake"};
int price[8]={180,120,65,55,70,70,110,200};
printf("\n *********");
printf("\n MENU CARD");
printf("\n *********\n\n\n\n");
printf("\n Food Code\t\tprice\t\t Food Name\n");
for(i=0;i<8;i++)
{
printf("\n\t\t%d",i+1);
printf("\t\t%d",price[i]);
printf("\t\t%s",food[i]);
}
printf("\n\n\n\t *PRESS 0 TO GO TO THE MAIN MENU\n\t *PRESS 1 TO ORDER
FOOD");
scanf(" %d",&answr);
switch(answr)
{
case 0:
{
printf("Enter the main menu function here");
break;
}
case 1:do
{
printf("ENTER THE FOOD CODE YOU WANT TO HAVE :: ");
scanf(" %d",&fc[z]);
z++;
tot=tot+fc[z];
printf("total so far is %d",tot);
printf("DO YOU WANT MORE(Y/N) ::");
scanf(" %c",&ans);
}while((ans=='y')||(ans=='Y'));
printf("\nEnter your room number:");
scanf(" %d",&room);
printf("\nEnter your name:");
scanf(" %s",&name);
}
}
The issue lies in your do loop. You need to initialize tot to 0, and use the user-inputted "food code" as an array index into your price array. I don't see any use for the "fc" array you've declared. This code should work for case 1 in your switch statement.
Remember that the main function returns an int in C.
do {
tot = 0;
printf("ENTER THE FOOD CODE YOU WANT TO HAVE :: ");
scanf("%d", &z);
if (z < 1 || z > 8) {
printf("Invalid food code\n");
return -1; // main should return int in a C program
}
tot=tot+price[z-1];
printf("total so far is %d\n",tot);
printf("DO YOU WANT MORE(Y/N) ::");
scanf(" %c",&ans);
} while((ans=='y')||(ans=='Y'));
I think that you should increment your counter z after you do the addition of the total with your freshly added element into the array.
1)Get the value by scanf
2)add it by using vet[z]
3)increment z.
When your code hit the sum it will try to access to a segment of memory that is filled with some other values.
I have a question in my paper. I have 10 employee ids M001,A004,D007,etc...User is inputting one of the the mentioned Ids and if the id is not there it prints id not found. I tired with strcmp and got stuck. Its good if you tell me a way to do it? Thanks, note: i am a beginner in C.I am trying an easy way now it gives the error with the for loop.
subscripted value is neither array nor pointer nor vector
#include<stdio.h>
#include<string.h>
float tSalary(float salary,float bonus);
char searchid(char search);
int main(void)
{
char status,input,search,C,P;
char searchId[8][4]={"M001","A004","D007","D010","D012","Q008","Q015","DE09"};
float salary,bonus,tSalary;
int i,j;
do{
printf("Enter the employee id: ");
scanf("%s", &search);
printf("Enter the job status: ");
scanf("%s", &status);
printf("Enter the salary: ");
scanf("%f", &salary);
for(i=0;i<8;i++){ //This is where all things go wrong
for(j=0;j<4;j++){
if(searchid[i][j]=search){ //the [i] where the subscripted error occurs
printf("Id is valid\n");
}
else printf("Invalid id\n");
}
}
printf("Do you want to enter another record?(Y-Yes/N-No): ");
scanf(" %c", &input);
}while(input=='Y'||input=='y');
return 0;
}
There are quite a few problems in the posted code. For starters, searchId should be declared as searchId[8][5], to make room for the \0 terminator at the end of each string.
It appears from the input code that status and search should hold strings, but these are declared as chars. After fixing this, note that there is no need for the address operator & in the calls to scanf() that read into these arrays. Also, maximum widths should always be specified when using the %s conversion specifier with scanf() to avoid buffer overflows.
Strings can not be compared using the == comparison operator, so strcmp() should be used here. This can be done in a loop that steps through the array of strings; the loop exits when the index reaches 8, or a comparison is successful. Then, after the loop, if the index has reached 8 (all valid id strings failed the test) the search string was not valid.
Here is a modified version of the posted code that implements all of this:
#include <stdio.h>
#include <string.h>
float tSalary(float salary,float bonus);
char searchid(char search);
int main(void)
{
char status[1000];
char search[1000];
char input, C, P;
char searchId[8][5] = { "M001", "A004", "D007", "D010",
"D012", "Q008", "Q015", "DE09" };
float salary, bonus, tSalary;
int i, j;
do {
printf("Enter the employee id: ");
scanf("%999s", search);
printf("Enter the job status: ");
scanf("%999s", status);
printf("Enter the salary: ");
scanf("%f", &salary);
i = 0;
while (i < 8 && strcmp(search, searchId[i]) != 0) {
++i;
}
if (i < 8) {
printf("Id is valid\n");
} else {
printf("Invalid id\n");
}
printf("Do you want to enter another record?(Y-Yes/N-No): ");
scanf(" %c", &input);
} while (input == 'Y' || input == 'y');
return 0;
}
Sample program interaction:
Enter the employee id: A004
Enter the job status: pending
Enter the salary: 2000
Id is valid
Do you want to enter another record?(Y-Yes/N-No): y
Enter the employee id: Q015
Enter the job status: completed
Enter the salary: 3000
Id is valid
Do you want to enter another record?(Y-Yes/N-No): y
Enter the employee id: B001
Enter the job status: completed
Enter the salary: 1200
Invalid id
Do you want to enter another record?(Y-Yes/N-No): n
I have been working on a college project. I want user to enter Y/N if he wants to continue or not, so I wrote following code
repeat:
pr=0;
q=0;
res=0;
printf("\nEnter the serial number of product you wish to purchase: ");
scanf("%d",&pr);
printf("Quantity: ");
scanf("%d",&q);
billing(pr,q);
printf("Continue Shopping? (y/n) ");
scanf("%d",&res);
if(res=='y')
goto repeat;
else
return 0;
}
The problem is entering y executes else statement. I tried replacing y with 1,2,3.... and it works but I want it to work with Y or y or yes.
There is a bug in this line
scanf("%d",&res);
It should be
scanf(" %c",&res);
The formatting placeholders for char is %c not %d
scanf("%d",&res);
should be
scanf(" %c",&res);
As suggested by multiple users do while should be used over goto, so better code would be
do{
pr=0;
q=0;
printf("\nEnter the serial number of product you wish to purchase: ");
scanf("%d",&pr);
printf("Quantity: ");
scanf("%d",&q);
billing(pr,q);
printf("Continue Shopping? (y/n) ");
scanf(" %c",&res);
}
while(*res == 'Y' || *res == 'y');
return 0;
}
Also res should also be declared char res;