How do I repeat entering data in a struct using C? - 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.

Related

Why can't I input the name and it kept coming up again before age [duplicate]

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.

String and for loop [duplicate]

This question already has answers here:
scanf() leaves the newline character in the buffer
(7 answers)
Closed 4 years ago.
I wrote this C program to enter names and ages of 3 people. But the output wasn't my expectation. It was able to enter name and age for the first person, but it wasn't able for second and third persons. Please help.
#include <stdio.h>
#include <string.h>
int main()
{
int i, age;
char name[20];
for(i=0; i<3; i++)
{
printf("\nEnter name: ");
gets(name);
printf("Enter age: ");
scanf(" %d", &age);
puts(name);
printf(" %d", age);
}
return 0;
}
In short: Your 2nd puts is processing the '\n' from your scanf.
Fix by adding getchar(); after scanf
Explanation:
1st iteration:
printf("\nEnter name: ");
gets(name); // line is read from input
printf("Enter age: ");
scanf(" %d", &age); // a number is read from input, and the newline char ('\n') remains in buffer
puts(name);
printf(" %d", age);
2nd iteration:
printf("\nEnter name: ");
gets(name); // previously buffered newline char is read, thus "skipping" user input
printf("Enter age: ");
scanf(" %d", &age);
puts(name);
printf(" %d", age);
Same goes for 3rd iteration, and this is why you lose user input
The best way to store information of more than one person is to use struct, like
struct person {
int age;
char name[20];
};
and make array of struct, like
struct person people[3];
than use loop with accessing people[i].age and people[i].name, e.g.:
#include <stdio.h>
#include <string.h>
struct person {
int age;
char name[20];
};
#define ARR_SIZE 3
int main(int argc, char* argv[])
{
struct person people[ARR_SIZE];
int i;
char *lastpos;
for(i = 0; i < ARR_SIZE; i++)
{
printf("\nEnter name: ");
scanf(" %s", people[i].name);
if ((lastpos=strchr(people[i].name, '\n')) != NULL) *lastpos = '\0'; // remove newline from the end
printf("Enter age: ");
scanf(" %d", &people[i].age);
}
printf("This is the people you entered:\n");
for(i = 0; i < ARR_SIZE; i++)
{
printf("%d : %s : %d\n", i+1, people[i].name, people[i].age);
}
return 0;
}
UPDATE:
As you see I use scanf(" %s", people[i].name); instead of gets(people[i].name); to read name from stdin. Try both option for the following cases:
enter short name (e.g. John) and correct age (e.g. 15)
enter two word name (e.g. John Smith) and correct age (e.g. 17)
enter short name and uncorrect age (e.g. five)
Then read articles about value returned by scanf and cleaning input buffer

C Program exits before taking input from user

Why does my program close before taking the input for k and then displaying it.
I am writing a code for a menu based program so I need to take input from user after he has entered the information so I can have 1.Print names 2.Exit
while doing this I realized my program didn't take the input and just skipped the part where it is supposed to take value of l from user. So trying to debug it I deleted stuff and came down to this simple program and realized it still wont work any idea why?
#include <stdio.h>
struct student
{
char name[50];
char lname[50];
float marks;
} s[15];
int main ()
{
int i, j,k;
printf("Please enter the number of students:\n");
scanf ("%d", &j);
printf ("Please enter the information for students as asked.\n");
for (i = 0; i < j; i++)
{
scanf ("%s %s %f\n", s[i].name, s[i].lname, &s[i].marks);
}
printf("Please enter a number\n");
scanf ("%d", &k);
printf("your number was %d", k);
return 0;
}
scanf ("%s %s %f\n", s[i].name, s[i].lname, &s[i].marks);
should be
scanf ("%s %s %f", s[i].name, s[i].lname, &s[i].marks);
The \n in scanf just consumes newline char. It will continue consuming newline until a non-newline char is found, which is put back into stdin for the next IO operation
Try this Code
#include<stdio.h>
typedef struct student
{
char name[50];
char lname[50];
int mark;
}S;
int main ()
{
int i, j,k;
printf("Please enter the number of students:\n");
scanf ("%d", &j);
S record[j];
for (i = 0; i < j; i++) {
printf ("Please enter the information for %d student as asked.\n",i+1);
scanf ("%s %s %f",record[i].name, record[i].lname, &record[i].mark);
}
printf("Please enter a number\n");
scanf ("%d", &k);
printf("your number was %d \n", k);
return 0;
}
You were declaring structure student array in the structure declaration itself.you have to declare the array in main function.

How to compare strings with user input?

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

Using pointers with structures to pass data to functions

This is a program for a class project. It is suppose to be able to create and edit structures. The CreatRec function works fine. For the ModifyRec I am trying to send it the array by pointers in order to avoid having to "copy" the data. However, I am having trouble getting it to actually change the array. ATM The line at the bottom (gr[change].lastname= *info;) is not working at all. I really have no clue what I am doing wrong here.
#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
struct student{
int recordname;
char lastname[10];
char firstname[10];
float math;
float english;
float science;
};
//prototypes
int menu();
struct student CreatRec(int);
void ModifyRec(struct student*);
void main()
{
int option, j;//option will be for users menu choice, j makes for loop work for creatrec
struct student grades[10];
j = 0;
option=Menu();
if (option == 1)
for (j = 0; j<10; j++)
(grades[j + 0]) = CreatRec(j);
else if (option==2)
ModifyRec(grades);//dont need & is smart bc array
printf("%s",grades[0].lastname);//This line is checking to see if ModifyRec actaully worked
//free(grades);2
while (1);
}
int Menu()
{
int choi;
printf("Please choose one of the following options.\n 1) Create New Student Records.\n 2) Modify an Existing Student Record\n");
printf(" 3) Print a New Sutdent Record.\n 4) Quit\n");
scanf("%d", &choi);
return choi;
}
struct student CreatRec(int i)
{
struct student qr;
//qr = (struct student*)malloc(sizeof(struct student)*6);
printf("RecordNum %i\n", i);
printf("Please enter last name-->");
scanf("%s", &qr.lastname);
printf("Please enter first name-->");
scanf("%s", &qr.firstname);
printf("Please math grade-->");
scanf("%f", &qr.math);
printf("Please english grade-->");
scanf("%f", &qr.english);
printf("Please science grade-->");
scanf("%f", &qr.science);
return qr;
}
void ModifyRec(struct student gr[])
{
int change;
char feild[10], info[10];
printf("Which record would you like to change?\n");
scanf("%d", &change);
rewind(stdin);
printf("Which feild would you like to edit?\n");
scanf("%s", &feild);
rewind(stdin);
printf("Enter info\n");
scanf("%s", &info);
if (!strcmp("lastname", feild))
gr[change].lastname= *info;//NOT WORKING
}
First of all I do not see a great sense in expression grades[j + 0] of statement
for (j = 0; j<10; j++)
(grades[j + 0]) = CreatRec(j);
These statements
printf("Please enter last name-->");
scanf("%s", &qr.lastname);
printf("Please enter first name-->");
scanf("%s", &qr.firstname);
have to be substituted for
printf("Please enter last name-->");
scanf("%s", qr.lastname);
printf("Please enter first name-->");
scanf("%s", qr.firstname);
And this statement
if (!strcmp("lastname", feild))
gr[change].lastname= *info;//
has to be substituted for
if (!strcmp("lastname", feild))
strcpy( gr[change].lastname, info );
gr[change].lastname is a char array, not a pointer. You can't reassign it. In this case, you probably ought to do scanf("%s", gr[change].lastname); and skip char info[10] altogether.

Resources