Array of Pointers to Structs referencing - c

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.

Related

Structure using Pointers and Function to store and retrieve data

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);
}

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.

Having trouble printing out my structure array in c

My current project in class is to make a program that acts as a phone book using structs. I have coded out the 'add contacts' function and the 'show contacts' function, but when I have more than one contact, the 'show contacts' function shows gibberish for all of the contacts expect for the most recent one. Can anybody help me find the problem?
Here is my current code. If anything is confusing let me know and I will try to respond as fast as I can.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct contact { // Data structure that holds contact information
char FirstName[10]; // Array for first name
char LastName[10]; // Array for last name
int PhoneNum; // Phone number
};
int main (){
// Setting up variables
int Function = 0;
int Choice = 0;
char FName[200][10];
char LName[200][10];
int PNum = 0;
int n = 1;
struct contact *con[200];
int b = 0;
do{ // Will loop through the main function until the user decides to exit the program
// Prints out the main menu of the phone book
printf("\nPhone Book");
printf("\n[1] Add a contact");
printf("\n[2] Delete a contact");
printf("\n[3] Show contacts");
printf("\n[4] Exit program");
printf("\n\nWhat function would you like to use?\n"); // Asks for user input
scanf("%d", &Choice);
switch(Choice){
case 1: // Case to add a contact into the phone book
printf("\nYou chose to add a contact.");
printf("\nFirst name: ");
scanf("%s", &FName[b]);
printf("\nLast name: ");
scanf("%s", &LName[b]);
printf("\nPhone number (Numbers only): ");
scanf("%d", &PNum);
printf("\nRecord added to the phone book");
// Records the information given into the structure
struct contact *con = (struct contact*)malloc(n*sizeof(struct contact));
int a = (n - 1);
printf("\na is %d", a);
strcpy(con[a].FirstName, FName[b]);
strcpy(con[a].LastName, LName[b]);
con[a].PhoneNum = PNum;
int b = (b+1);
n++;
printf("\nn is %d", n);
// Prints out the given information
printf("\nNew contact:");
printf("\nFirst name: %s", con[a].FirstName);
printf("\nLast name: %s", con[a].LastName);
printf("\nPhone number: %d", con[a].PhoneNum);
printf("\n");
break;
case 2: // Case to delete a contact from the phone book
printf("\nYou chose to delete a contact.");
break;
case 3: // Case to see all of the entered contacts
printf("\nYou chose to show the contacts.");
for(a = 0; a < (n - 1); a++){
printf("\nContact #%d", a);
printf("\nFirst name: %s", con[a].FirstName);
printf("\nLast name: %s", con[a].LastName);
printf("\nPhone number: %d", con[a].PhoneNum);
printf("\n");
}
break;
case 4:
printf("Goodbye!");
break;
}
}while (Choice != 4);
return 0;
}
This is the output I get when I run my code.
Phone Book
[1] Add a contact
[2] Delete a contact
[3] Show contacts
[4] Exit program
What function would you like to use?
1
You chose to add a contact.
First name: Test
Last name: 1
Phone number (Numbers only): 1234567
Record added to the phone book
a is 0
n is 2
New contact:
First name: Test
Last name: 1
Phone number: 1234567
Phone Book
[1] Add a contact
[2] Delete a contact
[3] Show contacts
[4] Exit program
What function would you like to use?
1
You chose to add a contact.
First name: test
Last name: 2
Phone number (Numbers only): 8901234
Record added to the phone book
a is 1
n is 3
New contact:
First name: test
Last name: 2
Phone number: 8901234
Phone Book
[1] Add a contact
[2] Delete a contact
[3] Show contacts
[4] Exit program
What function would you like to use?
3
You chose to show the contacts.
Contact #0
First name: Pq
Last name: q
Phone number: 1095516483
Contact #1
First name: test
Last name: 2
Phone number: 8901234
There are some issues on your code:
1> Scope of variable a, b, con should be in main function, you are override the scope of variable a, b from main function scope to in-case scope by re-declare them inside case block code.
int b = b+1;
int a = (n-1);
struct contact *con = (struct contact*)malloc(n*sizeof(struct contact));
In case block code, please just assign them new value:
b = b+1;
a = (n-1);
con = (struct contact*)malloc(n*sizeof(struct contact));
2> The con pointer should be changed from
struct contact *con[200];
by define a initialized size for it. and if the size is out of range, we need to realloc the con in case of add new item:
int size = 200;
struct contact *con = (struct contact *)malloc(size * sizeof(struct contact));
// in case of the size of out of range
if (n >= size)
{
size = size * 2;
con = (struct contact*)realloc(con, size * sizeof(struct contact));
}
Here is my solution:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct contact { // Data structure that holds contact information
char FirstName[10]; // Array for first name
char LastName[10]; // Array for last name
int PhoneNum; // Phone number
};
int main() {
// Setting up variables
int Function = 0;
int Choice = 0;
char FName[200][10];
char LName[200][10];
int PNum = 0;
int n = 1;
int size = 200;
struct contact *con = (struct contact *)malloc(size * sizeof(struct contact));
int b = 0, a = 0;
do { // Will loop through the main function until the user decides to exit the program
// Prints out the main menu of the phone book
printf("\nPhone Book");
printf("\n[1] Add a contact");
printf("\n[2] Delete a contact");
printf("\n[3] Show contacts");
printf("\n[4] Exit program");
printf("\n\nWhat function would you like to use?\n"); // Asks for user input
scanf("%d", &Choice);
switch (Choice) {
case 1: // Case to add a contact into the phone book
printf("\nYou chose to add a contact.");
printf("\nFirst name: ");
scanf("%s", &FName[b]);
printf("\nLast name: ");
scanf("%s", &LName[b]);
printf("\nPhone number (Numbers only): ");
scanf("%d", &PNum);
printf("\nRecord added to the phone book");
// Records the information given into the structure
if (n >= size)
{
size = size * 2;
con = (struct contact*)realloc(con, size * sizeof(struct contact));
}
a = (n - 1);
printf("\na is %d", a);
strcpy(con[a].FirstName, FName[b]);
strcpy(con[a].LastName, LName[b]);
con[a].PhoneNum = PNum;
b = (b + 1);
n++;
printf("\nn is %d", n);
// Prints out the given information
printf("\nNew contact:");
printf("\nFirst name: %s", con[a].FirstName);
printf("\nLast name: %s", con[a].LastName);
printf("\nPhone number: %d", con[a].PhoneNum);
printf("\n");
break;
case 2: // Case to delete a contact from the phone book
printf("\nYou chose to delete a contact.");
break;
case 3: // Case to see all of the entered contacts
printf("\nYou chose to show the contacts.");
for (a = 0; a < (n - 1); a++) {
printf("\nContact #%d", a);
printf("\nFirst name: %s", con[a].FirstName);
printf("\nLast name: %s", con[a].LastName);
printf("\nPhone number: %d", con[a].PhoneNum);
printf("\n");
}
break;
case 4:
printf("Goodbye!");
break;
}
} while (Choice != 4);
return 0;
}
You're defining a new variable called con inside of your switch statement. This variable mask the variable of the same name defined at the top of the function. This is the one you're adding a record to.
When you later go to print the list, it's actually reading from this inner con. However, since you're re-entering the switch statement, the variable's contents is uninitialized because you jump over the initializer because of the switch and you invoke undefined behavior. You get "lucky" that you're able to print the last instance read in, probably because the variable still happened to contain the old value from the last iteration.
Also, the outer version of con is declared as an array of pointers. You probably want just a pointer here so it can point to a dynamically allocated array.
So define con like this:
struct contact *con = NULL;
And change the "add" case to not define the variable. Also, you don't need separate variables to read in the values. You can read them directly into an instance of the struct:
n++;
con = realloc(n*sizeof(struct contact));
printf("\nYou chose to add a contact.");
printf("\nFirst name: ");
scanf("%s", con[n-1].FirstName);
printf("\nLast name: ");
scanf("%s", con[n-1].LastName);
printf("\nPhone number (Numbers only): ");
scanf("%d", &con[n-1].PhoneNum );
printf("\nRecord added to the phone book");
printf("\nn is %d", n);
printf("\nNew contact:");
printf("\nFirst name: %s", con[n-1].FirstName);
printf("\nLast name: %s", con[n-1].LastName);
printf("\nPhone number: %d", con[n-1].PhoneNum);
printf("\n");
Then you'll also need to move a down to the "show" portion:
for( int a = 0; a < (n - 1); a++){
As #Some programmer dude suggested you need to reallocate your array if you want to make it bigger and keep your data.
So essentially something like this
// Records the information given into the structure
struct contact *con = (struct contact*)malloc(n*sizeof(struct contact));
should be at the start of your main function like so:
// dynamically allocate memory which can hold e.g. 1 struct
struct contact *con = malloc(sizeof(struct contact));
and when you resize your memory chunk on the heap, that is what malloc does for you, you should resize or realloc it like so:
// grow array
con = realloc(con, n * sizeof(struct concat));
Read the man page for further Information: realloc man page, or type man 3 realloc or man realloc on your terminal.
EDIT
As #dbush suggested
You declare 2 variables named con. At the start struct contact *con[200]; and in the switch statement you allocate memory and save it into struct concat *con.
So the reason why you still get undefined results on option "3" (show all contact) is, that you actually are reading the contacts from the array struct contact *con[200]; and not from the memory pointed by struct contact *con;
Greetings

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.

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