How to make the series of questions asked? - c

Here is my code. I want it to ask me questions in a sequence. But whenever I enter my choice and put my name it didn't allow me to ask further. How to deal with that?
#include <stdio.h>
#include <stdlib.h>
int new_acc();
int main(){
int one=1, two=2, three=3, four=4, five=5, six=6, seven=7, new_account;
printf("-----WELCOME TO THE MAIN MENU-----\n\n");
printf("%d. Create new account\n",one);
printf("Enter you choice: ");
if (scanf("%d",&one)){
new_account = new_acc(); // calling a function
}
return 0;
}
int new_acc(){
int id; char name;
printf("Enter your name: ");
scanf("%c\n",&name);
printf("Enter your ID card number: ");
scanf("%d\n",&id);
return 0;
}

If you typed Enter after typing nubmer for the MAIN MENU, the newline character remains in the buffer.
Then, is is read as the name via %c.
After that, if you typed, for example, alphabet as name, it will prevent it from reading the number id.
To avoid this, you can put a space before %c to have it skip the newline character.
Also you won't be have to skip after reading name and id, so you should remove \n in scanf() after %c and %d for them.
int new_acc(){
int id; char name;
printf("Enter your name: ");
scanf(" %c",&name); /* add space and remove \n */
printf("Enter your ID card number: ");
scanf("%d",&id); /* remove \n */
return 0;
}
By the way, the above code will allow only one alphabet as name.
To support multi-character name (without space character), you should use an array of char and %s with length specified.
int new_acc(){
int id; char name[1024];
printf("Enter your name: ");
scanf(" %1023s",name); /* don't use & here, and size limit is buffer size - 1 (-1 for terminating null character) */
printf("Enter your ID card number: ");
scanf("%d",&id);
return 0;
}
If you want to support name with space characters, you can use %[\n] (read until newline character) instead of %s.
int new_acc(){
int id; char name[1024];
printf("Enter your name: ");
scanf(" %1023[^\n]",name);
printf("Enter your ID card number: ");
scanf("%d",&id);
return 0;
}

Seems like you want to use an object oriented programming paradigm in this. To so do, you should define an "object" with struct and save the new account with that:
#define MAX 50
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Account {
int id;
char name[MAX];
};
struct Account new_acc();
int main(){
int choice;
struct Account new_account;
printf("-----WELCOME TO THE MAIN MENU-----\n\n");
printf("1. Create new account\n");
printf("Enter you choice: ");
scanf("%d",&choice);
switch(choice) {
case 1:
new_account = new_acc();
break;
default:
printf("Not a valid option\n");
return 1;
}
return 0;
}
struct Account new_acc(){
char name[MAX];
int id;
struct Account new;
printf("Enter your name: ");
scanf("%c\n",name);
printf("Enter your ID card number: ");
scanf("%d\n",&id);
strcpy(new.name, name);
new.id = id;
return new;
}
Pay attention because this code is very vulnerable to buffer overflows. Plus, I edited your check for the option in main because scanf returns 1 if reads whatever value successfully.

Use This Code i have modfified a little bit
int new_acc(){
int id; char name[10];
printf("Enter your name: ");
scanf("%s",name);
printf("Enter your ID card number: ");
scanf("%d",&id);
return 0;
}

Related

fprintf function in code writes garbage data into .csv file

I'm trying to create a C program which collect's an applicant's information. When a user is prompted to enter their written subjects, the program writes rubbish data into the .csv file when they wrote one. And sometimes does the same when the number of subjects written is two.
I've tried to clear the buffer stream, but it's no use. Strangely, using different compliers like DevC++, Embarcadero DevC and VS Code produces different results.
Edit: I've also noticed the chances of the rubbish values being written into the file are lowered when the grades of the subjects is lower than the number of subjects written.
Attached below is the code. And an image of the output.
// C libraries.
#include <stdio.h> // Contains function prototypes for the standard input/output library functions, and information used by them.
#include <conio.h> // Contains function prototypes for the console input/output library functions.
#include <stdlib.h> // Contains function prototypes for conversions of numbers to text and text to numbers, memory allocation, random numbers and other utility functions.
#include <string.h> // Contains function prototypes for string-processing functions.
#include <time.h> // Contains function prototypes and types for manipulating the time and date.
#include <stdbool.h> // Contains macros defining bool, true and false, used for boolean variables.
struct Applicant
{
int applicationID;
int dateOfApplication;
char lastName[21];
char firstName[21];
char middleName[21];
char dateOfBirth[21];
int age;
char gender;
char address[100];
char phoneNumber[21];
char emailAddress[51];
char mobileNumber[21];
int numSubjectsWritten;
char csecSubjects[20][100];
char grades[20];
char programmeSelection[10];
};
struct Applicant getApplicantData()
{
struct Applicant applicant;
int i = 0;
int numSubjects;
// Asking for applicant input for various fields.
printf("| Personal |");
printf("\nEnter Last Name: ");
scanf(" %20s", &applicant.lastName);
fflush(stdin);
printf("\nEnter First Name: ");
scanf(" %20s", &applicant.firstName);
fflush(stdin);
printf("\nEnter Middle Name (If you don't have a middle name, leave this field blank.): ");
gets(applicant.middleName);
fflush(stdin);
/*
printf("\nEnter Date of Birth: ");
scanf(" %s", &applicant.dateOfBirth);
fflush(stdin);
printf("\nEnter Gender. 'M' for male, 'F' for female, (M|F): ");
scanf(" %c", &applicant.gender);
fflush(stdin);
printf("\n\n| Contact Information |");
printf("\nEnter Address: ");
gets(applicant.address);
fflush(stdin);
printf("\nEnter Phone Number: ");
gets(applicant.phoneNumber);
fflush(stdin);
printf("\nEnter Email Address: ");
gets(applicant.emailAddress);
fflush(stdin);
printf("\nEnter Mobile Number: ");
gets(applicant.mobileNumber);
fflush(stdin);
*/
printf("\n\n| Education |");
printf("\nEnter Number of Subjects Written: ");
scanf("%d", &applicant.numSubjectsWritten);
fflush(stdin);
while (i < applicant.numSubjectsWritten)
{
printf("\nEnter the subject: ");
gets(applicant.csecSubjects[i]);
fflush(stdin);
printf("\nEnter the grade for that subject: ");
scanf(" %c", &applicant.grades[i]);
fflush(stdin);
i++;
}
return applicant;
}
int main(void)
{
FILE *file = fopen("Data.csv", "a+");
int i, j;
if (!file)
{
printf("\nError! Can not open data file.\nPlease contact the Program Addmission Manager as soon as possible with the error message.");
exit(1);
}
else
{
struct Applicant applicant = getApplicantData();
//fprintf(file, "%s:%s:%s:%s:%c:%s:%s:%s:%s", applicant.lastName, applicant.firstName, applicant.middleName, applicant.dateOfBirth, applicant.gender, applicant.address, applicant.phoneNumber, applicant.emailAddress, applicant.mobileNumber);
fprintf(file, "%s:%s:%s:", applicant.lastName, applicant.firstName, applicant.middleName);
for (i = 0; applicant.csecSubjects[i][0] != '\0'; i++)
{
fprintf(file, " %s", applicant.csecSubjects[i]);
fflush(stdout);
fflush(stdin);
fflush(file);
fprintf(file, " ( %c):", applicant.grades[i]);
fflush(stdout);
fflush(stdin);
fflush(file);
}
}
return 0;
}
First problems I see:
Remove the & from all instances where you scanf a string
Don't use gets, or mix scanf and fgets
Don't fflush(stdin)
Instead of scanf, consider using a custom-made input method with condition checking and anything you need. I will give an example.
#define BUFFER_SIZE 512
void input(char* buffer){
memset(buffer, 0, BUFFER_SIZE); // Initializing the buffer.
fgets(buffer, BUFFER_SIZE, stdin);
strtok(buffer,"\n");
}
How to take input using that?
void main(){
int username[BUFFER_SIZE];
input(username);
}
A way to write a structure to a file is shown below.
void Structure_Print(Applicant* applicant, FILE* stream, int no_of_applicant){
if(no_of_applicant==0){
fprintf(stdout, "No applicant yet.\n");
return;
}
fprintf(stream, "%s:%s:%s:", applicant.lastName, applicant.firstName, applicant.middleName);
for (i = 0; applicant.csecSubjects[i][0] != '\0'; i++)
{
fprintf(stream, " %s:", applicant.csecSubjects[i]);
fprintf(stream, " %c:", applicant.grades[i]);
}
return;
}
Also, I noticed how you tried to make it readable while saving it in subject(grade) format. I recommend you to not do that. Your .csv file is just for database. Nobody is going to read it. So just store the data by comma or any character separator. It will make it easier to extract data later.

Assignment to expression with array type error, char array value unable to be set to a variable in structure

I am taking a very basic C course, and I have run into a problem. My code is supposed to take someone's info, create a profile, and then print the information at the end. Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
typedef struct record
{
char lastname[30];
char firstname[30];
int id;
char gender;
int monthOfBirth;
int dayOfBirth;
int yearOfBirth;
} HealthProfile;
void setID(HealthProfile *HPP){
int id;
printf("please enter your ID: ");
scanf("%d", &id);
HPP->id=id;
}
void setGender(HealthProfile *HPP){
char gender;
printf("please enter yomeur M or F for your gender: ");
scanf("%c",&gender);
HPP->gender=gender;
}
void setFirstName(HealthProfile *HPP){
char firstname[30];
printf("please enter your first name: ");
scanf("%s",&firstname);
HPP->firstname=firstname;
}
void setLastName(HealthProfile *HPP){
char lastname[30];
printf("please enter your last name: ");
scanf("%s",&lastname);
HPP->lastname=lastname;
}
void setDoB(HealthProfile *HPP){
int dayOfBirth;
printf("please enter your DoB: ");
scanf("%d", &dayOfBirth);
HPP->dayOfBirth=dayOfBirth;
}
void setMoB(HealthProfile *HPP){
int monthOfBirth;
printf("please enter your MoB: ");
scanf("%d", &monthOfBirth);
HPP->monthOfBirth=monthOfBirth;
}
void setYoB(HealthProfile *HPP){
int yearOfBirth;
printf("please enter your YoB: ");
scanf("%d", &yearOfBirth);
HPP->yearOfBirth=yearOfBirth;
}
int main()
{
HealthProfile *HPP;
HPP=(HealthProfile*) malloc(sizeof(HealthProfile));
setID(HPP);
setGender(HPP);
setLastName(HPP);
setFirstName(HPP);
setDoB(HPP);
setMoB(HPP);
setYoB(HPP);
printf("\n Profile information.....");
printf("ID number: %d\n", HPP->id);
printf("Gender: %c\n", HPP->gender);
printf("Name: %s/n",HPP->firstname);
printf(" %s", HPP->lastname);
printf("Month of birth: %d\n", HPP->monthOfBirth);
printf("Day od birth: %d\n", HPP->dayOfBirth);
printf("Year of birth: %d\n", HPP->yearOfBirth);
}
The part that is giving me the error is these two lines:
**HPP->lastname=lastname;**
and
**HPP->firstname=firstname;**
Whenever I try to run it the equal sign is highlighted red and my code gives me the "assignment to expression with array type" error. Even after looking it up and trying things for almost two hours I couldn't figure it out, so can someone help me, please?
The fields HPP->lastname and HPP->firstname are both arrays, and as the error message states you cannot assign directly to an array.
The way you copy one string to another is to use the strcpy function:
strcpy(HPP->firstname, firstname);
Of course, you can get rid of the copy altogether and read directly into the target array instead of a temporary.
scanf("%s", HPP->firstname);

C - Passing Structure Parameters to Function By Reference and Value

Could I please have an explanation of what I am doing wrong.The program is for inputting and displaying student details. It must use a structure and have 2 functions; one to capture(which is to be passed by reference) and another to display (which is to be passed by value.
Here is my code:
#include <stdio.h>
struct Students{
int ID;
char name[50];
int age;
char address[100];
char course[30];
} aStudent[5];
void capture(char *name , int *age , char *address, char *course){
int i;
for(i=0; i<5; i++){
aStudent[i].ID = i+1;
printf("\nFor Student number %d:\n",aStudent[i].ID);
printf("Enter Student Name: ");
scanf ("%s", &aStudent[i].name);
printf("Enter Student Age: ");
scanf ("%d", &aStudent[i].age);
printf("Enter Student Address: ");
scanf ("%s", &aStudent[i].address);
printf("Enter Course: ");
scanf ("%s", &aStudent[i].course);
}
}
void display(char name, int age , char address, char course){
int i;
for(i=0; i<5; i++){
printf("\nStudent %d:\n",aStudent[i].ID);
printf("Name: %s\t\tAge: %d\t\tAddress: %s\t\tCourse:
%s",aStudent[i].name, aStudent[i].age, aStudent[i].address,
aStudent[i].course);
printf("\n");
}
}
void main()
{
int option, age;
char name, address, course;
printf("\t...Welcome to the Student Data System...\n\n");
printf("\nPlease Select An Option: \n1. Input Student Data\n2. View
Student Data\n3. Exit Syatem\n\n");
scanf("%d",&option);
switch(option){
case 1:
printf("Enter Student Details:\n");
capture(name, age , address, course);
break;
case 2:
printf("\nDisplaying Information:\n");
display(name, age , address, course);
break;
case 3:
close();
break;
default:
printf("\nSorry, your option is not valid.");
}
}
I have tested a number of times and it's working, but I'm getting these error messages:
Errors are shown for every argumety I've used
Also, is there a way or a line(s) of code i can use to return to the start of the switch when I am done with one of the cases - A "Return to Main Menu"?
First of all, variables you have tried to pass (either by value or by reference) when you are calling the two functions capture() and display(), haven't used anywhere because you are dealing directly with the members of the structure Students when you are capturing or displaying the results.
And the reasons you are getting syntax errors are because the capture() is expecting the addresses of the variables (&name,&age,&address,&course) and you are passing variables (name,age,address,course) themselves. And also you are using,
scanf ("%s", &aStudent[i].name);
instead of
scanf ("%s", aStudent[i].name);
In my opinion instead of making the Structure array global, declaring it inside main function and passing the whole structure array to the capture() as a reference and passing it by value to the display() is better to your objective as you need to use both call by value and reference in your code.
I have edited your code a bit and added the return to main menu option. It works for me and I apologize if my answer is long and hard to understand because this is my first answer in stackoverflow. Thanks!
#include <stdio.h>
struct Students
{
int ID;
char name[50];
int age;
char address[100];
char course[30];
};
void capture(struct Students *aStudent)
{
int i;
for(i=0; i<2; i++)
{
aStudent[i].ID = i+1;
printf("\nFor Student number %d:\n",aStudent[i].ID);
printf("Enter Student Name: ");
scanf ("%s", aStudent[i].name);
printf("Enter Student Age: ");
scanf ("%d", &aStudent[i].age);
printf("Enter Student Address: ");
scanf ("%s", aStudent[i].address);
printf("Enter Course: ");
scanf ("%s", aStudent[i].course);
}
}
void display(struct Students aStudent[])
{
int i;
for(i=0; i<2; i++)
{
printf("\nStudent %d:\n",aStudent[i].ID);
printf("Name: %s\t\tAge: %d\t\tAddress: %s\t\tCourse: %s",aStudent[i].name, aStudent[i].age, aStudent[i].address,aStudent[i].course);
printf("\n");
}
}
void main()
{
struct Students aStudent[2];
int option;
char choice = 'Y';
printf("\t...Welcome to the Student Data System...\n\n");
while(choice == 'Y' || choice == 'y')
{
printf("\nPlease Select An Option: \n1. Input Student Data\n2. View Student Data\n3. Exit Syatem\n\n");
scanf("%d",&option);
switch(option)
{
case 1:
printf("Enter Student Details:\n");
capture(aStudent);
printf("Return to main menu? (Y/N) :");
scanf(" %c",&choice);
break;
case 2:
printf("\nDisplaying Information:\n");
display(aStudent);
printf("Return to main menu? (Y/N) :");
scanf(" %c",&choice);
break;
case 3:
close();
break;
default:
printf("\nSorry, your option is not valid.");
}
}
}
You have not initialized your string instead you have initialized a character! char name, address, course; If you have used 'char *name, *address, *course;' or char name[100], address[100], course[100]; you might have got the answer ! If you use the above case you should scan using scanf("%s",name); ! Hope I answered your question !

Restrict User To Enter Integers?

Hello I Want To Ask A Question About That How i Restrict User From Enter Integers And Enter Only String OR Characters.
If You Know The Answer Can You Fit That In My Code Below that Would be great if you do that btw forget the date part its just other thing.
void checkin()
{
char comp_choice,more_choice,in_comp_choice;
int comp_amount;
int date_month[] = {31,28,31,30,31,30,31,31,30,31,30,31};
int date_month1[] = {31,28,31,30,31,30,31,31,30,31,30,31};
int charges_per_room_per_day = 5000,bill;
struct info user;
system("cls");
printf("\t\tCHECK IN FORM\n");
printf("Please Fill Following Information\n");
FILE *fp;
fp = fopen("checkin.txt","a");
time_t t;
time(&t);
printf("First Name : ");
fflush(stdin);
gets(user.first_name);
printf("Last Name : ");
fflush(stdin);
gets(user.last_name);
fflush(stdin);
printf("Contact Number : ");
gets(user.contact_no);
fflush(stdin);
printf("\nGuests : ");
scanf("%d",&user.guest);
printf("Rooms : ");
scanf("%d",&user.rooms);
fprintf(fp,"%s %s %s %d %d\n",user.first_name,user.last_name,user.contact_no,user.guest,user.rooms);
Label2:
printf("Today date and time is %s\n",ctime(&t));
printf("Check In date (DD-MM-YYYY) : ");
scanf("%d %d %d",&user.date,&user.month,&user.year);
printf("Check out date (DD-MM-YYYY) : ");
scanf("%d %d %d",&user.date1,&user.month1,&user.year1);
This Is Image of i am entering Integers And Program Doesn't Say Any Thing
A way to enforce a user entering a valid integer is to read in whatever the user enters (e.g. into a char[..]-buffer), and then to interpret/check the result as required. For this check, you can then either write your custom logic, or use the logic of built in functions, like, for example, strol.
The following sample makes use of strtol. The signature of strtol is long int strtol(const char *nptr, char **endptr, int base). Basically, after a successful scan, endptr will point to the first character of nptr after the (successfully) scanned number; if we do not accept any characters after a (valid) number, we check if endptr actually points to string terminator '\0'; in the case of an unsuccessful scan, endptr is equal to nptr.
Here you go:
#include <stdio.h>
#include <stdlib.h>
int enterIntegerValue(const char *message) {
char inputBuffer[21];
char *endOfScan;
bool error;
int result;
do {
printf("%s", message);
scanf("%20s", inputBuffer);
result = (int)strtol(inputBuffer,&endOfScan,10);
error = (endOfScan == inputBuffer) || (*endOfScan != '\0');
if (error)
printf("Invalid number. Please enter a valid integer number.");
}
while (error);
return result;
}
int main()
{
int rooms = enterIntegerValue("Rooms : ");
printf("input: %d", rooms);
return 0;
}

Console C Program stopped working dev c++

I was practicing array of structure. I made the following program and there were no compiling errors.But when i try to run it(I guess these errors are called runtime errors?),it stops working just after accepting the roll number. I wonder what wrong i did.
I use Dev c++ and gcc compiler.
Here's the code:
#include<stdio.h>
struct student{
char Fname[];
char Lname[];
int reg_no;
int Class;
char sec;
};
void enterinfo(student *,int);
void Display(student *,int);
int main()
{
int i;
printf("\t\t\t Enter student's information\n\n\n\n");
printf("How many students are there in you're school: ");
scanf("%d",&i);
student ob[i],*ptr;
ptr=ob;
enterinfo(ptr,i);
Display(ptr,i);
}
void enterinfo(student *e,int y)
{
char CONT='y';
for (int j=0;j<y && (CONT=='y' || CONT=='Y');j++)
{
printf("Enter Students First Name: ");
scanf("%s",e->Fname);
printf("Enter Students Last Name: ");
scanf("%s",e->Lname);
printf("Enter Roll number: ");
scanf("%d",e->reg_no);
printf("Enter class: ");
scanf("%d",e->Class);
printf("Enter Section: ");
scanf("%d",e->sec);
printf("\n\n\n\n Do you want to enter more? : ");
scanf("%c",&CONT);
}
}
void Display(student *e,int y)
{
char CONT='y';
for (int j=0;j<y;j++)
{
printf("Students name : %s %s",e->Fname,e->Lname);
printf("Enter Roll number: %d",e->reg_no);
printf("class: %d",e->Class);
printf("Enter Section: %d",e->sec);
}
}
I've made the following changes to your code and it started working for me:
char Fname[]; --> char Fname[100];
char Lname[]; --> char Lname[100];
char sec; --> int sec; This is needed for scanf.
scanf("%d",e->reg_no); --> scanf("%d",&e->reg_no);
scanf("%d",e->Class); --> scanf("%d",&e->Class);
scanf("%d",e->sec); --> scanf("%d",&e->sec);
adding \n to the end of printf strings in Display
Please note that scanf("%s", ...) is insecure and it can cause a crash the input string is longer than the array size you're reading it to, i.e. if the user types a name of at least 100 bytes.
Please note that you should always check the return value of scanf, and abort early on error (i.e. if it doesn't return 1 in your case).
Please note that in C++ the istream methods (http://en.cppreference.com/w/cpp/header/istream) provide a safer way to read the input.
Here:
scanf("%d",e->reg_no);
you should insert a '&' symbol before e->reg_no. But I can see many other problems once you solve this...
You can use below code, it will run on both linux & windows. Your program halts because of:
scanf("%d",&e->reg_no);
printf("Enter class: ");
scanf("%d",&e->Class);
printf("Enter Section: ");
scanf("%d",&e->sec);
you did not use & which is must for int, char, float data types as it is used as reference of the variable.
#include
struct student{
char Fname[30];
char Lname[30];
int reg_no;
int Class;
char sec[5];
};
void enterinfo(student *,int);
void Display(student *,int);
int main()
{
int i;
printf("\t\t\t Enter student's information\n\n\n\n");
printf("How many students are there in you're school: ");
scanf("%d",&i);
student * ob = new student[i];
enterinfo(ob,i);
Display(ob,i);
}
void enterinfo(student *e,int y)
{
char CONT='y';
for (int j=0;jFname);
printf("Enter Students Last Name: ");
scanf("%s",e->Lname);
printf("Enter Roll number: ");
scanf("%d",&e->reg_no);
printf("Enter class: ");
scanf("%d",&e->Class);
printf("Enter Section: ");
scanf("%s",e->sec);
getchar();//to eat newline/ enter char of previous statement
printf("\n\n\n\n Do you want to enter more? : ");
scanf("%c",&CONT);
}
}
void Display(student *e,int y)
{
for (int j=0;jFname,e->Lname);
printf("\nEnter Roll number: %d",e->reg_no);
printf("\nclass: %d",e->Class);
printf("\nEnter Section: %s\n",e->sec);
}
}

Resources