Structure using Pointers and Function to store and retrieve data - c

struct account
{
struct //A structure inside a structure
{
char lastName[10];
char firstName[10];
} names; //structure is named as 'name'
int accountNum;
double balance;
};
int main()
{
struct account record;
int flag = 0;
do
{
nextCustomer(&record);
if ((strcmp(record.names.firstName, "End") == 0) && //only when the first name entered as "End"
(strcmp(record.names.lastName, "Customer") == 0)) //and last name entered as "Customer", the loop stops
flag = 1;
if (flag != 1)
printCustomer(record);
}
while (flag != 1);
}
void nextCustomer(struct account *acct)
{
printf("Enter names (firstName lastName):\n");
//scanf("%s, %s", acct->firstName, acct->lastName); //have no idea why first and last name cant be found although im aware thats its a structure inside a structure
printf("Enter account number:\n");
//scanf("%d", acct->accountNum);
printf("Enter balance:\n");
scanf("%f", acct->balance);
}
void printCustomer(struct account acct)
{
printf("Customer record: \n");
printf("%d", acct.accountNum); //can't seem to retrieve data from the strcture
}
Hi guys, i am new to c, and i managed to hardcode data on structures, and print our their respective value. Currently, i am working on using a pointer to store the respective data, as well as function to print out their data. Can anyone help me on why i cant store and retrieve my data? I dont need the answers, just the logic flow is sufficient.

Followin changes are needed to your nextCustomer function, you are directly accessing firstName and lastName using acct, but they are present inside names
so you have to use acct->names.firstName and acct->names.lastName
void nextCustomer(struct account *acct)
{
printf("Enter names (firstName lastName):\n");
scanf("%s%s", acct->names.firstName, acct->names.lastName); //have no idea why first and last name cant be found although im aware thats its a structure inside a structure
printf("Enter account number:\n");
scanf("%d", &acct->accountNum);
printf("Enter balance:\n");
scanf("%lf", &acct->balance);
}
void printCustomer(struct account acct)
{
printf("Customer record: \n");
printf("F: %s\n", acct.names.firstName);
printf("L: %s\n", acct.names.lastName);
printf("A: %d\n", acct.accountNum); //can't seem to retrieve data from the strcture
printf("B: %lf\n", acct.balance);
}

Related

How to search each record in file properly using "fseek()"

I am working in this program and I'm having difficulties in the part i have to find and overwrite one part of the data.
I stored the students in ab mode.When I print the data in file that are stored they look fine.But when i wanna use fseek() to find the data, something goes wrong.
In this case i wanna find one of the students by Id and replace their ID. The problem is that I can only replace and fund the first person data. Others result like they don't exist.
void change_id()
{
int long pos;
int id_temp;
int new_id;
FILE *ftemp;
ftemp=fopen(file_person,"rb+");
if(ftemp==NULL)
{
printf("\nError in file!");
return;
}
while(fread(&nr1[nr_person],sizeof(struct person),1,ftemp))
{
printf("\nGive the person Id:");
fflush(stdin);
scanf("%d",&id_temp);
rewind(ftemp);
fseek(ftemp,sizeof(struct person)*(id_temp-1),SEEK_SET);
if(id_temp==nr1[nr_person].id)
{
printf("\nGive the new ID:");
scanf("%d",&new_id);
nr1[nr_person].id=new_id;
fwrite(&nr1[nr_person],sizeof(struct person),1,ftemp);
break;
}
else {
printf("Id doesnt exist!");
return;
}
Maybe I didn't store correctly the students.
Here is what I did:
struct person{ //This is the struct i have done
int id;
char name[20];
int pass;
}nr1[50];
int nr_person; //I was trying to use this like a student count
void register_person()
{ //I'm I using the number person wrong?
FILE *f;
f=fopen("person.txt","ab");
if(f==NULL){
printf("Error!");
return ;
}
nr_person++;
nr1[nr_person].id=read_data(file_person);
printf("Generated Id is %d",nr1[nr_person].id);
printf("\nName : ");
scanf("%s",nr1[nr_person].name);
nr1[nr_person].pass=generate_password(nr1[nr_person].id,nr1[nr_person].name);
fwrite(&nr1[nr_person],sizeof(struct person),1,f);
if(fwrite!=0){
printf("\n\n Data saved");}
else printf("\nData not saved!");
fclose(f);
}
I have been struggling with this part. Can anyone help me?
Thanks in advance!

I want to store the сustomer information in an array of customers

this for adding new costumer.
typedef struct date{
int d,m,y;
}date;
typedef struct client{
int *id;
char *nom [30];
char *prenom [30];
date date;
char *adresse[30] ;
char *tel [30];
}client;
client cl;
void ajouter (){
int age;
printf("give first name:\n");
scanf("%s",&cl.nom);
printf("give last name:\n");
scanf("%s",&cl.prenom);
printf("give adresse:\n");
scanf("%s",&cl.adresse);
printf("give tel num:\n");
scanf("%s",&cl.tel);
printf("give date of birth :\n");
scanf("%d %d %d",&cl.date.d, &cl.date.m, &cl.date.y);
cl.id=1;
if(2019-cl.date.y<18)
printf("refuse");
else
printf(" succes\n");
printf("your informations:\n");
printf(" first name: %s \n last name: %s \n adresse: %s \n tel num: %s \n date of birth : %d/%d/%d \n ID: 0000000%d",cl.nom,cl.prenom,cl.adresse,cl.tel,cl.date.d,cl.date.m,cl.date.y,cl.id);
cl.id++;
}
the problem is when i add the 1st costumer i dont know how to store the informations
i want to save it without using files.
i am beginner and i know maybe its wrong what am doing
but am trying to do my best to make this code
int main()
{
int a,age;
char t[100];
printf("----------- menu ------------\n");
printf("add customer : 1\n");
printf("remove customer : 2\n");
printf("search for customer : 3\n");
scanf("%d",&a);
switch(a){
case(1):ajouter(a);break;
}
return 0;
}
i didnt finish it yet
Salut,
If I understood well, you wish to store a client's data in an array in RAM.
I believe you are using C, hence vectors are not really an option.
So instead, you have either the option of having an array of fixed size, which could be useful in certain situations but generally not, or having a dynamic array, which can be kind of hard to understand when begginning but you shouldn't have much trouble.
In the case a fixed-size array works for you, here's an example of how you'd do it:
//Declaring the client array
#define nClientsTableau 100
int nClients = 0;
client clients[nClientsTableau];
...
//Adding a new client, keep in mind it's just an example
ajouter();
clients[nClients] = cl;
nClients++;
if(nClients == nClientsTableau) printf("Max amount of clients reached");
Then for the second option, building a dynamic array. Different ways of doing it exist, here is a simple way to perform it for your code:
//Declaring the client array
client* clients = NULL;
client* clients2 = NULL;
int nClients = 0
//Adding a new client
ajouter();
nClients++;
clients2 = (client*)realloc(clients, nClients * sizeof(client));
clients = clients2; //NOTE: You should probably check for clients2 not being NULL first
clients[nClients - 1] = cl;
//Ending the program
free(clients);
I sincerely hope this helps. Apart from that, I'd like to tell you that your code is excellent for a beginner, just try having some naming conventions.

how do I print the stuct members using an array pointers?

The code I have wrote so far is the following without the libraries. Basically I used the stdio.h and the stdlib.h.
typedef struct ID{
char firstName[21];
char lastName[21];
char phoneNumber[11];
}ID;
ID PrintList(ID *ptr,int i){
int l=1;
printf(" # First Name Last Name Phone Number\n");
while(l<i+1)
{
printf(" %d. %s",l,&ptr[l]);
l++;
}
}
ID addNew(ID *ptr,int i){
char fname[21],lname[21],phone[11];
if(i<3)
{
ID user;
ptr[i] = user;
printf("enter the first name: ");
scanf("%s",&fname);
*ptr->firstName= fname;
printf("enter the last name: ");
scanf("%s",&lname);
*ptr->lastName = lname;
printf("enter the phone number: ");
scanf("%s",&phone);
*ptr->phoneNumber = phone;
}
else
{
printf("sorry but you have reach max capacity\n");
}
}
int main(int argc, char *argv[]) {
int answere,i=0;
printf("******* WELCOME TO PHONEBOOK **********\n\n\n");
printf("***************************************\n");
printf("* MENU *\n");
printf("* *\n");
printf("* 1.Add New 2.Print list 3.Exit *\n\n");
printf("***************************************\n\n");
ID* ptr=(int*)malloc(21*sizeof(ID));
do
{
printf("Please select (1, 2 or 3): ");
scanf("%d",&answere);
if(answere!=1 && answere!=2 && answere!=3)
{
printf("...Error... \ngive me a correct answere\n");
}
if(answere == 1)
{
i++;
addNew(ptr,i);
}
else if(answere==2)
{
PrintList(ptr,i);
}
}while(answere!=3);
return 0;
}
So as I said my problem is that I am not able to print the members of the struct as I need to print them using the array of pointers though. I think that I just haven't written something right like it is just a little logic mistake in printf.
The only obstacle that I have is that the array of pointers is needed to be made in main.
You seem completely lost...
Some Basics
You are passing pointer/reference to first item of an array (address of the first item)
to get value at that address (dereference it) you can do two things:
*ptr //but I don't recommend using it with structures
ptr[0]
since you are using structures that are generally big you are expected to work with pointers and for that reason so called "arrow" operator exists which can be used to access members of structure pointer
ptr->firstName
So your function would look like this:
void PrintList(ID *ptr, int l)
{
int i;
printf(" # First Name Last Name Phone Number\n");
for(i = 0; i < l; i++)
{
printf("%2d. %s %s %s\n",
i, ptr[i].firstName, ptr[i].firstName, ptr[i].phoneNumber);
}
}
Also I recommend using '\t' instead of spaces to align the columns.

Array of Pointers to Structs referencing

I'm writing a "nano social network", just by registering a member and connecting them using pointers in a structure. I'm trying to use a connect function in which I'm not sure I'm writing it in a correct way because the program crashes when I try to run it and I get 0 errors and 0 warnings (warnings at high level using CodeBlocks).
First I register at least 2 members and then when I try to connect them via the connect() function I get that the user I wish to connect with does not exist which is part of the condition in the function. Is it that the users I'm registering don't get saved in the memory? Or am I writing something wrong?
The connect function can be simplified by all means but I will do that once I'm clear with my mistakes.
The code:
#include <stdio.h>
#include <stdlib.h>
struct member{
int num;
char name[10];
struct member *m1;
struct member *m2;
struct member *m3;
struct member *m4;
struct member *m5;
}*ptr[5];
void addmember(){
int i;
printf("Enter new members details:\n");
for(i=0; i<4; i++){
ptr[i] = malloc(sizeof(struct member));
printf("\n Enter ID number:\n");
scanf("%d", &ptr[i]->num);
printf("\n Enter Name:\n");
scanf("%s", ptr[i]->name);
}
printf("\n Added member details are:");
for(i=0; i<4; i++){
printf("\n ID number : %d", ptr[i]->num);
printf("\nName : %s", ptr[i]->name);
}
}
void connect(){ //when always typing the first username
int i=0;
printf("Please type in your user name : \n");
scanf("%s", ptr[i]->name);
if(ptr[i]->name == ptr[0]->name){ //being first user connecting.
printf("Please type existing member name you wish to connect with :\n");
scanf("%s", ptr[i]->name);
if(ptr[i]->name == ptr[1]->name){
ptr[0]->m1 = ptr[1]->m1;
ptr[1]->m2 = ptr[0]->m2;
printf("member 1 connected with member 2!\n");
}
else if(ptr[i]->name == ptr[2]->name){
ptr[0]->m1 = ptr[2]->m1;
ptr[2]->m3 = ptr[0]->m3;
printf("member 1 connected with member 3!\n");
}
else if(ptr[i]->name == ptr[3]->name){
ptr[0]->m1 = ptr[3]->m1;
ptr[3]->m4 = ptr[0]->m4;
printf("member 1 connected with member 4!\n");
}
else if(ptr[i]->name == ptr[4]->name){
ptr[0]->m1 = ptr[4]->m1;
ptr[4]->m5 = ptr[0]->m5;
printf("member 1 connected with member 5!\n");
}
else{
printf("User you typed in does not exist\n");
}
}
}
int main(){
int op = 0;
printf("Welcome to NSN, please register 4 members to proceed to options menu.\n");
addmember(); //adding 4 members
//general member section
printf("Now please select an option by typing option number\n");
while(op != 3){
printf("\n");
printf("1. Add new member.\n 2. Connect with member.\n 3. Exit\n");
printf("Enter your choice:\n");
scanf("%d", &op);
switch(op){
case 1:
addmember();
break;
case 2:
connect();
break;
case 3:
printf("Bye!\n");
exit(0);
break;
default:
printf("Invalid choice!\n");
}
}
return(0);
}
As stated before when I use the connect function after having registered at least 3 members and typing an existing name I always get the answer "User you typed in does not exist", is this somehow that I'm not saving this in memory or am I missing a function?
You cannot compare char arrays like this, you're comparing addresses these pointers point to:
ptr[i]->name == ptr[0]->name
You have to use strcmp function:
strcmp(ptr[i]->name, ptr[0]->name)
And also, think about your connect function - why is it using the first member for input - scanf("%s", ptr[i]->name);? You rather want to type in member A and B's names, find their positions in ptr array, then connect them.
I also don't get why you have these five pointers to member in member itself. You already have an array.

How to approach and optimize code in C

I am new to C and very much interested in knowing how to approach any problem which has more than 3 or 4 functions, I always look at the output required and manipulate my code calling functions inside other functions and getting the required output.
Below is my logic for finding a students record through his Id first & then Username.
This code according to my professor has an excessive logic and is lacking in many ways, if someone could assist me in how should I approach any problem in C or in any other language it would be of great help for me as a beginner and yes I do write pseudo code first.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
int id; //Assuming student id to be unique
int age;
char *userName; //Assuming student userName to be unique
char *dept;
}student; // Alias "student" created for struct
student* createstruct(); // All function prototype declared
student* createArray();
void addstruct(student* s2);
void searchChar(student* s2,int num);
void searchInt(student* s2,int num);
student* createstruct() // function createStruct() to malloc data of struct student.
{
student *s;
s = (student*)malloc(sizeof(student));
s->userName = (char*)malloc(sizeof(char)*32);
s->dept = (char*)malloc(sizeof(char)*32);
printf("please enter id ");
scanf("%d",&s->id);
printf("please enter age ");
scanf("%d",&s->age);
printf("please enter userName ");
scanf("%31s",s->userName);
printf("please enter department ");
scanf("%31s",s->dept);
printf("\n");
return s;
}
student* createArray()
{
student *arr; //declaration of arr poiter, type struct student
arr = (student*)malloc(sizeof(student)*10); // memory allocated for a size of 10
return arr;
}
void addstruct(student *s2) // function for adding data to the structures in array
{
int i,num;
student* s1;
printf("please enter the number of records to add:");
scanf("%d",&num);
printf("\n");
if(num>0 && num<11)
{
for(i=0;i<num;i++) // if user want to enter 5 records loop will only run 5 times
{
s1 = createstruct();
s2[i].id = s1->id; // traversing each element of array and filling in struct data
s2[i].age = s1->age;
s2[i].userName = s1->userName;
s2[i].dept= s1->dept;
}
}
else if(num>10) // if user enters more than 10
{
for(i=0;i<10;i++) // loop will still run only 10 times
{
s1 = createstruct();
s2[i].id = s1->id;
s2[i].age = s1->age;
s2[i].userName = s1->userName;
s2[i].dept = s1->dept;
}
printf("Array is full"); // Array is full after taking 10 records
printf("\n");
}
searchInt(s2,num); // Calling searchInt() function to search for an integer in records
searchChar(s2,num); // Calling searchChar() function to search for a string in records
free(s1);
free(s2);
}
void searchChar(student* s2,int num) // function for searching a string in records of structure
{
char *c;
int i;
c = (char*)malloc(sizeof(char)*32);
printf("please enter userName to search ");
scanf("%31s",c);
printf("\n");
for (i=0;i<num;i++) //num is the number of struct records entered by user
{
if ((strcmp(s2[i].userName,c)==0)) //using strcmp for comparing strings
{
printf("struct variables are %d, %d, %s, %s\n", s2[i].id,s2[i].age,s2[i].userName,s2[i].dept);
break;
}
else if(i == num-1)
{
printf("nothing in userName matches: <%s>\n",c);
break;
}
}
}
void searchInt(student* s2,int num) //searchs for an integer and prints the entire structure
{
int i,z;
printf("please enter id to search ");
scanf("%d",&z);
printf("\n");
for (i=0;i<num;i++)
{
if (s2[i].id == z)
{
printf("struct variables are %d, %d, %s, %s\n\n", s2[i].id,s2[i].age,s2[i].userName,s2[i].dept);
break;
}
else if(i == num-1)
{
printf("nothing in id matches: <%d>\n\n",z);
break;
}
}
}
int main(void)
{
student *s2;
s2 = createArray();
addstruct(s2);
return 0;
}
I'm not going to go into optimizing, because if you wanted better theoretical performance you would probably go with different data structures, such as ordered arrays/lists, trees, hash tables or some kind of indexing... None of that is relevant in this case, because you have a simple program dealing with a small amount of data.
But I am going to tell you about the "excessive logic" your professor mentioned, taking your searchInt function as an example:
for (i=0;i<num;i++)
{
if (s2[i].id == z)
{
printf("struct variables are %d, %d, %s, %s\n\n", s2[i].id,s2[i].age,s2[i].userName,s2[i].dept);
break;
}
else if(i == num-1)
{
printf("nothing in id matches: <%d>\n\n",z);
break;
}
}
The thing here is that every time around the loop you're testing to see if you're at the last element in the loop. But the loop already does that. So you're doing it twice, and to make it worse, you're doing a subtraction (which may or may not be optimized into a register by the compiler).
What you would normally do is something like this:
int i;
student *s = NULL;
for( i = 0; i < num; i++ )
{
if( s2[i].id == z ) {
s = &s2[i];
break;
}
}
if( s != NULL ) {
printf( "struct variables are %d, %d, %s, %s\n\n",
s->id, s->age, s->userName, s->dept );
} else {
printf("nothing in id matches: <%d>\n\n",z);
}
See that you only need to have some way of knowing that the loop found something. You wait for the loop to finish before you test whether it found something.
In this case I used a pointer to indicate success, because I could then use the pointer to access the relevant record without having to index back into the array and clutter the code. You won't always use pointers.
Sometimes you set a flag, sometimes you store the array index, sometimes you just return from the function (and if the loop falls through you know it didn't find anything).
Programming is about making sensible choices for the problem you are solving. Only optimize when you need to, don't over-complicate a problem, and always try to write code that is easy to read/understand.

Resources