printing with type long - c

I'm working on my school project form data structure and I'm having a problem with the type long.
I want to design a small project like a university registration system.
First the person get to chose if he want to register or exit.
If he want to register then he will enter his name and gpa to select the major that is available based on his gpa and the system will generate an id automatically.
The problem is the id is not incremented correctly.
Additional info:
I'm using doubly linked list structure
#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<string.h>
struct student{
char name[30];
int GPA;
unsigned long ID;
char colloege[100];
student *next, *prev;
};
student *stu, *cur, *head, *tail;
void insertfront();
void displaylist(){
unsigned long id=214000000;
cur=head;
printf(" ");
if(cur==NULL)
printf(" ");
else
while(cur!=NULL){
printf("Name:%s\t",cur->name);
printf("ID:%d\t",cur->ID=id++);
printf("GPA:%d\t",cur->GPA);
printf("Colloege of:%s\t",cur->colloege);
printf("\n");
cur=cur->next;
}
}
void main(){
clrscr();
int x;
printf("\n\t\t\t\t******* King Faisal University *********\n");
while(x!=2){
printf("\n press 1 to insert your information ,press 2 to exit\n");
scanf("%d",&x);
insertfront();
displaylist();
}
stu=NULL;
cur=NULL;
head=NULL;
tail=NULL;
getch();
}
void insertfront(){
int x,c;
stu=(student*)malloc(sizeof(student));
fflush(stdin);
printf("Enter your name:\n");
scanf("%[^\n]%*c",stu->name);
printf("Enter your GPA:\n");
scanf("%ul",&stu->GPA);
printf("\n Available Colloeges\n");
if(stu->GPA>=85)
{
printf("1.Colloege of Medicine\n 2.Colloege of Engenering\n 3.Colloege of Computer Science\n 4.Colloege of Business\n 5.Colloege of Art\n");
printf("Enter the colloege number \n");
scanf("%d",&c);
switch(c){
case 1: strcpy(stu->colloege,"Medicien");break;
case 2: strcpy(stu->colloege,"Engenering");break;
case 3: strcpy(stu->colloege,"Computer Science");break;
case 4: strcpy(stu->colloege,"Business");break;
case 5: strcpy(stu->colloege,"Art");break;
}
}
else if(stu->GPA>=75)
{
printf("1.Colloege of Computer Science\n 2.Colloege of Business\n 3.Colloege of Art\n");
printf("Enter the colloege number\n");
scanf("%d",&c);
switch(c){
case 1: strcpy(stu->colloege,"Computer Science");break;
case 2: strcpy(stu->colloege,"Business");break;
case 3: strcpy(stu->colloege,"Art");break;
}
}
else
strcpy(stu->colloege,"Art");
if(head==NULL)
{
stu->next=NULL;
stu->prev=NULL;
head=stu;
tail=stu;
}
else
{
stu->next=head;
stu->prev=NULL;
head->prev=stu;
head=stu;
}
}

You are using an incorrect conversion in your program
printf("ID:%d\t",cur->ID=id++);
// cur->ID is of type unsigned long
// %d is used for values of type int
To print a value of type long you need to use "%ld" in the printf() conversion
long longvalue = 42;
printf("%ld\n", lonvgalue);
To print a value of type unsigned long you need to use "%lu" in the printf() conversion
unsigned long ulongvalue = 42;
printf("%lu\n", ulongvalue);

In addition to the format specifier being wrong, you have a problem with assigning ID:s.
Your code assigns new ID:s every time you display the list.
I would generate the ID only once for each student record, when the record is created.
So add this in insertfront:
stu->ID=id++;
and change the printing in displaylist to:
printf("ID:%lu\t",cur->ID);
and move the declaration of id either to global scope (outside of any function) or as a static variable inside insertfront:
static unsigned long id=214000000;

Related

Having problems displaying structure array content

I want to display structure members based on user input, but I don't know if I've stored the input properly.
When I try display all people, it just outputs random numbers.
These are the structures and function prototypes
#define MAX_NAME_LEN 15
#define MAX_NUM_PERSON 4
#define MAX_JOB_LENGTH 20
typedef struct birth_date
{
int month;
int day;
int year;
} person_birth_t;
typedef struct person
{
char pName[MAX_NAME_LEN];
char job[MAX_JOB_LENGTH];
person_birth_t birth_t;
} person_t[MAX_NUM_PERSON];
void print_menu (void);
void scanPerson(person_t p, int);
void displayPeople(person_t p);
This is the main code for the program, a menu is printed asking user to input a number, if a user enters 1 then it prompts them to add a person. Entering 2 displays all people entered.
int main(void)
{
/* TODO */
print_menu();
return 0;
}
void print_menu (void)
{
int choice;
person_t p;
static int index = 0;
int *indexP = NULL;
indexP = &index;
/*Print the menu*/
scanf("%d", &choice);
switch (choice)
{
case 1:
if (index < MAX_NUM_PERSON){
scanPerson(p, index);
++*indexP;
print_menu();
} else {
printf("Can't add more people - memory full \n");
print_menu();
}
break;
case 2:
displayPeople(p);
break;
case 3:
exit(0);
break;
default:
print_menu();
}
}
/*function called when add person is chosen from menu */
void scanFlight(person_t p, int index){
/*printf to enter name*/
scanf(" %s", p[index].pName);
/*printf to enter job*/
scanf("%s", p[index].job);
}
void displayPeople(person_t p){
for(int i = 0; i < MAX_NUM_PERSON; i++){
printf("%s %d-%d-%d %s \n",p[i].pName
,p[i].birth_t.month
,p[i].birth_t.day
,p[i].birth_t.year
,p[i].job);
}
}
I've tried other ways to take input and add it to a struct array, but I'm just not sure how to do it right.
person_t p;
Here, you use the local variable p (in print_menu function), so each recursion, you just print the parameters of the local variable that is not initialized.
To solve it, you can declare p as the global variable.
OT, in scanFlight function, to avoid overflow, you should change the scanf function to:
/*printf to enter name*/
scanf("%14s", p[index].pName);
/*printf to enter job*/
scanf("%20s", p[index].job);
And, rename scanPerson to scanFlight, because i do not see any implementation of scanPerson function in your code. I think it's typo, no ?
None of the methods were working, so instead of trying to figure it out, I scrapped the static index and indexP.
Instead, I initialized p with malloc:
person_t *p= malloc(MAX_NUM_PERSON * sizeof(person_t));
I changed the scan function to accommodate for the change and made index a pointer instead, and I made the display function pass the index.
When I ran it, the output was correct.

So many errors and not sure how to fix it

I'm currently still practicing my c programming skills but there are so many errors here that I'm confuse on what is wrong and how to fix it. It's for a database program that I was practicing on.
It keeps showing:
new2.c:86: error: request for member ‘previousreading’ in something not a structure or union
and
new2.c:94: error: ‘Break’ undeclared (first use in this function)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
int custid;
char custname;
float currentreading;
float previousreading;
double charge;
int choice;
unsigned cust;
int revenue, meterdifference, BILL;
printf("----------------------------------\n");
printf("Electricity Management System\n");
printf("----------------------------------\n");
printf("\n1. Record Usage");
printf("\n2. Add Customer");
printf("\n3. Edit Customer");
printf("\n4. Delete Customer");
printf("\n5. Show Customer");
printf("\n6. Show Total monthly income");
printf("\n7. Exit");
scanf("%d",&choice);
if(choice >=1 || choice <=7)
{
switch(choice)
{
case 1: //Record Usage
printf("Enter Customer ID\n");
FILE *cfPtr;
if ((cfPtr = fopen("customer.txt", "r"))== NULL)
puts("This file could not be opened");
else
{
puts("Enter the customer ID, name.");
scanf("%d%29s", &cust.custid, cust.custname);
puts("Enter the current reading in kWh");
scanf("%d", cust.currentreading);
if(cust.currentreading < cust.previousreading)
puts("Input invalid");
else
{
if (cust.currentreading>=200)
{
cust.charge = (cust.currentreading - cust.previousreading)*21.80;
printf("\nThe charge is RM%f\n", &cust.charge);
}
else
{
if (cust.currentreading>=300)
{
cust.charge= ((cust.currentreading - cust.previousreading)*33.40)+21.80;
printf("\nThe charge is RM%f", &cust.charge);
}
else
{
if (cust.currentreading>=600)
{
cust.charge= ((cust.currentreading - cust.previousreading)*51.60)+21.80;
printf("\nThe charge is RM%f", &cust.charge);
}
else
{
if (currentreading>=900)
{
cust.charge = ((cust.currentreading - cust.previousreading)*54.60)+21.80;
printf("\nThe charge is RM%f", &cust.charge);
}
else
{
cust.charge = ((cust.currentreading - cust.previousreading)*57.10)+21.80;
printf("\nThe charge is RM%f", &cust.charge);
}
}
}
}
}
}
Break;
case2: //Add Customer
puts("This option allows user to add new customer");
printf("Enter Customer ID and name.");
scanf("%d%c", &cust.custid, cust.custname);
puts("To return to menu");
Break;
case 3: //Edit Customer
puts( "This option allows user to edit customer info");
Break;
case 4: //delete customer
puts( "This option allows user to delete customer");
Break;
case 5: //Show Customer
printf("To show customer information\n");
FILE*tPtr;
char custid[100],custname[100];
int previousreading,currentreading;
double charge;
printf("\n Show Customer\n");
if((tPtr= fopen("customer.txt","r"))==NULL){
puts("File not found");
}
else{
printf("%-15s%-25s%-20s%-15s%-15s\n","ID","Name","Previous Reading","Current Reading","Charges");
while(!feof(tPtr)){
fscanf(tPtr,"%[^;];%[^;];%d;%d;%lf",cust.custid,cust.custname,&cust.previousreading,&cust.currentreading,&cust.charge);
printf("%s\t\t%-25s%-20d%-15d%-15.2lf",cust.custid,cust.custname,cust.previousreading,cust.currentreading,cust.charge);
}
fclose(tPtr);
}
printf("\n\n");
Break;
case 6: //Show total income(monthly)
puts("To show monthyly income");
printf("total usagekWh, meterdifference");
printf("%-15s%-35.2d\n", "Total UsagekWh","meterdifference");
scanf("%-16dtotal usage(kWh)%-24d: %.2f",&meterdifference);
printf("%-13dtotal revenue%-24d: %.2f",BILL);
revenue=BILL;
printf("revenue is %.2f", BILL);
Break;
case 7: //Exit
Break;
}
}
else
printf("\nError. Number not in choices.");
return 0;
}
typedef struct{
int custid[50];
char custname[100];
int previousreading;
int currentreading;
float charges;
}cust;
Put the typedef before main. typedefs must occure before you use them just as vaiables.
Replace unsigned cust; by cust cust;. unsigned cust; is the same as unsigned int cust; and declares an unsigned integer, you want to declare a cust.
Replace float charges; by float charge; in the typedef
Replace Break; by break;. Case matters in C. Break is not Break, just as Int is not int.
Then it compiles.
Now if it it runs correctly or not is another story.
There is not a single structure in your code, not in the form of a variable declaration nor as a type definition1, and you are treating cust which is simply an unsigned int as if it was a structure, perhaps you mean
struct {
float previousreading;
float currentreading;
/* And so on */
} cust;
Also, there is no Break keyword in c, it's break, all lower case.
But,
Don't do it, create a new struct so that you can use declare variables of type struct Costumer for example. Like at the end of your code, except that the compiler needs to know about it before using it, and the cust variable should have it's type.
A char is not a string type, if you want a string you need an array of char, so char custname; is not going to work for the name string.
Use meaningful names for your variables, and the members if your structure and the type name too. Like costumer instead of cust.
Additional NOTE
See Why while (!foef(file)) is always wrong. Your code will always attempt a read with fscanf() that will fail but it proceeds to print the data, it's very likely that your last row is printed twice once you make the code compile.
Instead, check the return value of fscanf(), if you don't know what it returns and don't fully understand it you can always read fscanf(3) documentation.
1At least not before you attempt to use it.

Storing record of 100 employees using c language

Using c language how we can store 100 employees record like employee name,designation,salary in variables and how we can access them.
Conceptually in a nutshell, you can first create an "Emp" structure(struct), with attributes such as name, salary etc... Then create an array of (100) such Emp structs.
To access it, you just loop through this array, for each struct, you can access name, salary, etc..
Hope that helps.
Here an example:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSTR 50
#define MAXEMPLOYEES 100
typedef struct {
char name[MAXSTR];
char designation[MAXSTR];
float salary;
} Employee;
typedef struct {
Employee employeesArray[MAXEMPLOYEES];
int count;
} Employees;
void initEmployees(Employees*);
Employee readEmployee();
void addEmployee(Employees*, Employee);
void showAllEmployees(Employees);
int main()
{
int choice;
Employee newEmployee;
Employees employeesArchive;
initEmployees(&employeesArchive);
do{
printf("1. Add new Employee.\n");
printf("2. Show all Records.\n");
printf("0. Exit.\n");
printf("Select: ");
scanf("%d", &choice);
switch(choice){
case 1:
newEmployee = readEmployee();
addEmployee(&employeesArchive, newEmployee);
break;
case 2:
showAllEmployees(employeesArchive);
break;
}
}while(choice!=0);
return 0;
}
void initEmployees(Employees *_employees){
_employees->count = 0;
}
Employee readEmployee(){
Employee _newEmployee;
printf("NEW RECORD\n");
printf("-> Name: ");
scanf("%s", _newEmployee.name);
printf("-> Designation: ");
scanf("%s", _newEmployee.designation);
printf("-> Salary: ");
scanf("%f", &_newEmployee.salary);
return _newEmployee;
}
void addEmployee(Employees *_employees, Employee _newEmployee){
int index;
index = _employees->count;
strcpy(_employees->employeesArray[index].name, _newEmployee.name);
strcpy(_employees->employeesArray[index].designation, _newEmployee.designation);
_employees->employeesArray[index].salary = _newEmployee.salary;
_employees->count++;
printf("New Employee correctly added!\n");
system("pause");
}
void showAllEmployees(Employees _employees){
int i, allRecords;
allRecords = _employees.count;
for(i=0; i<allRecords; i++){
printf("#%d\nName: %s\tDesignation: %s\tSalary: %f\n",
i+1,
_employees.employeesArray[i].name,
_employees.employeesArray[i].designation,
_employees.employeesArray[i].salary);
printf("\n");
}
}
Better you create a linked list.
It's type of data structure in which you have to create a object which contain all information (of employee in this case) along with a pointers which point to other objects of list.
(Based on your question I must suggest you to Read what data structure is before moving forward..)
There are several types of data structures like single linked list ,circular linked list , double link list , tree , etc.. But here you can try most basic e.g. single link list for your requirement.
#include<stdio.h>
#include<stdlib.h>
#define LEN=20;
//this is our object definition
typedef struct EMPLOYER
{
char name[LEN],designation[LEN];
int salary;
struct EMPLOYER* next_object;
};
void add_employer_details();
void print_employers_details();
EMPLOYER** main_pointer;
char op;
int main()
{
printf("shall we start storing data of employee...?(y/n)\n");
scanf(" %c",&op);
while(op=='y' || op=='Y')
//to add new employee's detail
add_employer_detail();
//print whole database
print_employers_detail();
}
void add_employer_detail()
{
//creating a node
EMPLOYER *temp;
//allocating memory
temp=(EMPLOYER*)malloc(sizeof(EMPLOYER));
printf("enter details of employer...\n");
//feeling the data
gets(temp->name);
gets(temp->designation);
scanf("%d",&(temp->salary));
//making the link with other nodes
temp->next=main_pointer;
main_pointer=temp;
printf("want a new entry?(y/n)");
scanf(" %c",&op);
}
void print_employer_detail()
{
EMPLOYER* temp=*main_pointer;
while(temp)
{
printf(" name of employee : %20s\n designation of employee : %20s\n salary of employee : %8d\n",temp->name,temp->designation,temp->salary);
temp=temp->next;
}
}
Its always a good habit to allocate memory dynamically when it comes to data management system.But you always make sure that you are deallocating memory once you no longer need it to avoid memory leak. :)

Taking in unique inputs in a struct array in C

I am writing a program to create a structure named 'student'. I need to input various data about a particular student. Here is my program till now.
#include<stdio.h>
#include<stdlib.h>
struct student
{
char* name;
int id;
float marks_1;
float marks_2;
};
void main()
{
int num, var_i, var_j, var_k, var_l, duplicated_id = 0;
printf("Enter number of students\n");
scanf("%d", &num);
struct student s[num];
printf("Enter the data for the students\n");
for (var_i = 0; var_i < num; var_i++)
{
var_j = var_i + 1;
printf("Enter name of student_%d\n", var_j);
scanf(" %[^\n]%*c", &s[var_i].name);
printf("Enter id of student_%d\n", var_j);
scanf("%d", &s[var_i].id);
for (var_k = 0; var_k < var_i; var_k++)
{
if (s[var_k].id == s[var_i].id)
{
printf("Duplicate Id, program will exit");
return;
}
}
printf("Enter marks(sub_1) of student_%d\n", var_j);
scanf("%d", &s[var_i].marks_1);
printf("Enter marks(sub_2) of student_%d\n", var_j);
scanf("%d", &s[var_i].marks_2);
}
}
In the following for loop I am checking all the previously entered 'id' values to check if there is a duplicate. In case of a duplicate, the program will exit.
for(var_k=0;var_k<var_i;var_k++)
{
if(s[var_k].id==s[var_i].id)
{
printf("Duplicate Id, program will exit");
return;
}
}
Now instead of exiting the program I want to prompt the user to enter a different value. This goes on till he enters a unique value. How should I do it?
Any help appreciated.
This is wrong:
scanf(" %[^\n]%*c", &s[var_i].name);
You're passing the address of the pointer member name (i.e. you're passing a char **) to scanf() which per the format string, is expecting a char* and enough memory to hold the data it subsequently reads. This is invalid, is undefined behavior, and blindly overwrites data in the s[] array. Frankly I'm amazed this doesn't seg-fault your process.
Change this:
struct student
{
char* name;
int id;
float marks_1;
float marks_2;
};
To this:
struct student
{
char name[128]; // or some other suitable size.
int id;
float marks_1;
float marks_2;
};
And change this:
scanf(" %[^\n]%*c", &s[var_i].name);
To this:
scanf(" %[^\n]%*c", s[var_i].name);
I strongly suggest a size-limiter on that scanf() call as well, but I leave that to you to discover. Read about the API here.
Just use a loop.
here is some psudocode
bool isDuplicate = false
do
{
GetInput()
isDuplicate = CheckForDuplicate()
}while(isDuplicate);

Why does this give junk value?

I am getting garbage / junk values as output when my program is run and the data displayed.
Why is it so?
Can someone help me to understand how to properly pass by pointers and not get junk values?
This program is about stack creation of struct books type variables.
By default shouldn't the variable bks pass by pointer and change when b is changed?
bks is still storing garbage value.
Here is my code:
#include<stdio.h>
#include<stdlib.h>
struct books
{
int yrpub;
char name[100],author[50];
};
int top=-1;
int push(struct books b[],int top,int n)
{
if(top==n-1)
return -1;
else
{
++(top);
printf("Enter books info: \n");
printf("Enter name: ");
gets(b[top].name);
printf("Enter author: ");
gets(b[top].author);
printf("Enter Year of publish: ");
scanf("%d",&b[top].yrpub);
return top;
}
}
void display(struct books b[],int top)
{
int i;
if(top==-1)
printf("No books in the stack...");
for(i=0;i<=top;i++)
{
printf("Details of book %d: \n",i+1);
printf("Name: %s\nAuthor: %s\nYear of publish: %d\n",b[i].name,b[i].author,b[i].yrpub);
}
system("pause");
}
int main()
{
struct books bks[10];
int ch;
system("cls");
printf("Select an option:\n");
printf("1. Push book\n2. Pop book\n3. Peep book\n4. Display all books info\n5. Exit\n");
printf("Enter a choice: ");
scanf("%d",&ch);
fflush(stdin);
switch(ch)
{
case 1:
system("cls");
top=push(bks,top,10);
break;
case 4:
system("cls");
display(bks,top);
break;
case 5: exit(0);
default: printf("\nWrong choice...Please retry.");
long i,j;
for(i=0;i<1000000;i++)
for(j=0;j<100;j++);
}
main();
}
Each time you recursively call main(), you create a new array bk.
The information you entered in the previous invocation of main() is hidden from the new one.
To iterate is human; to recurse, divine.
In this context, give up divinity for humanity. Use iteration — in this context it is better.
This is your primary problem; there may also be other off-by-one or other errors.
push:
if(top==n-1)
return -1;
main:
top=push(bks,top,10);
top is reset when the stack is full
Edit:
And the second problem is main being called again, struct books bks[10] is reset in the next main, it is a recursion. Declare bks as global or go with a while loop instead of recursion.
while (1) {
getChoices();
if (exit)
/* exit from here */
process();
}

Resources