How do i sort structure array with pointers? - c

Write a program to enter id, name, and address to a structure array and sort them in ascending order on the basis of the name with the use of pointer?
I tried searching for so many questions in this forum, but none of them exactly helped me out. So this is my code:
#include<stdio.h>
struct student
{
char name[20], add[30];
int id;
};
int main()
{
struct student s[100];
struct student *sptr;
int i, j, temp, n;
char tempc[30];
sptr=&s;
printf("How many students do we have to register?");
scanf("%d",&n);
printf("Enter the id, name and address of the students and hit enter.");
for (i=0; i<n; i++)
{
scanf("%d%s%s",&sptr->id,&sptr->name,&sptr->add);
sptr++;
}
sptr=&s;
for(i=0; i<n; i++)
{
for(j=i+1;j<n;j++)
{
if(strcmp(s[i].name,s[j].name)>0)
{
strcpy(tempc,(sptr+i)->name);
strcpy(sptr->name,(sptr+j)->name);
strcpy((sptr+j)->name,tempc);
strcpy(tempc,sptr->add);
strcpy(sptr->add,(sptr+j)->add);
strcpy((sptr+j)->add,tempc);
temp=(sptr+j)->id;
sptr->id=(sptr+j)->id;
(sptr+j)->id=temp;
}
}
}
printf("The sorted form is:");
for (i=0; i<n; i++)
{
printf("%d%s%s",sptr->id,sptr->name,sptr->add);
sptr++;
}
}
If you're getting where I'm going, please help me out. And yeah I don't want to use any memory allocation functions or sizeof() function.

Simply use qsort like following:
int compare_student (const void * a, const void * b)
{
struct student *lhs = (struct student *)a;
struct student *rhs = (struct student *)b;
return strcmp( lhs->name, rhs->name) ;
}
// N = total number of students;
qsort (s, N, sizeof(struct student), compare_student);

Related

Array of struct with pointer

typedef struct line {
int a;
int b;
} line;
int main() {
line *v;
int c, d, j;
char a;
int i;
scanf("%d", &n)
for (i = 0; i < n; i++) {
scanf("%c", &a);
v = (line*) malloc(n * sizeof(line));
if (a == '+') {
scanf("%d %d", &v[j]->a, &v[j]->b);
}
}
I want to make an array that holds a struct info, and then use that info in my function . But I am getting some errors and I don't know if I used well the pointer.
I have tried with v[j].a but it didn't work. (I used this because I am more familiar from linked-list.)
Use &(v[j].a) instead, which is equal to &((v+j)->a). The name of an array is a pointer to the first element. So v[j] is an element of type struct line. In order to get one of its fields you use .a.
Also, check your code for some other errors because some variebles are not initialized.
First of all you malloc a new memory on every iteration and the previous one becomes unavailable.
Abstracting from the logic of the program
typedef struct line {
int a;
int b;
} line;
int main(void) {
line *v;
int c, d, j;
char a;
int i,n;
scanf("%d", &n);
v = malloc(n * sizeof(line));
if(v == NULL) return -1;
for (i = 0; i < n; i++) {
scanf("%c", &a);
if (a == '+') {
scanf("%d %d", &v[j].a, &v[j].b);
}
}
}

qsort for structures

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
typedef struct Student
{
char nume[20];
int grupa,nr_credite;
} S;
int cmpg(const void *a, const void *b);
int cmpc(const void *a, const void *b);
void ex();
int main()
{
ex(); //main program
return(0);
}
void ex() //sorting function
{
int n,i,c;
S st[100];
scanf("%d", &n);
for(i=0; i<n; i++)
scanf("%s %d %d", st[i].nume, &st[i].grupa, &st[i].nr_credite);
size_t no = sizeof(S)/sizeof(st->grupa);
size_t noo = sizeof(S)/sizeof(st->nr_credite);
qsort(st->grupa, no, sizeof(S), cmpg);
qsort(st->grupa, noo, sizeof(S), cmpc);
for(i=0; i<n; i++)
printf("%s %d %d", st[i].nume, &st[i].grupa, &st[i].nr_credite);
}
int cmpg(const void *a, const void *b)
{
struct Student *ia = (struct Student *)a;
struct Student *ib = (struct Student *)b;
return (int)(ia->grupa - ib->grupa);
}
int cmpc(const void *a, const void *b)
{
struct Student *ia = (struct Student *)a;
struct Student *ib = (struct Student *)b;
return (int)(ib->nr_credite - ia->nr_credite);
}
So the thing is I have some students in some different groups and they have a different number of credits. I want to use qsort to order them by group (ascending) and inside of each group to sort them by the number of credits(descending).
I have this code but it is stopping with this exit code: Process terminated with status -1073741819 (0 minute(s), 11 second(s)).
The problem comes from your calls of qsort. What qsort expects is the array to sort, the number of elements that should be sorted, the size of each element and the comparison function. So what you need is:
qsort(st, n, sizeof(S), cmpg);
qsort(st, n, sizeof(S), cmpc);
And your printf is also wrong:
for(i=0; i<n; i++)
printf("%s %d %d", st[i].nume, st[i].grupa, st[i].nr_credite);
BTW, you never test for errors which is bad:
if n>100, you will get an out of bond access on S
if there is an incorrect value in one the the answers, you will have read errors but still proceed with indeterminate values.
As noted in comments, this only fixes the error. But as qsort is not required to be a stable sort, two consecutive sorts may not produce what you want.
You want this:
void ex()
{
int n, i;
S st[100];
scanf("%d", &n);
for (i = 0; i<n; i++)
scanf("%s %d %d", st[i].nume, &st[i].grupa, &st[i].nr_credite);
qsort(st, n, sizeof(S), cmpg);
// ^ ^ ^
// | | |
// | | size of one element
// | |-- number of elements in array
// |-- address of first element of the array
//
qsort(st, n, sizeof(S), cmpc);
for (i = 0; i<n; i++)
printf("%s %d %d\n", st[i].nume, st[i].grupa, st[i].nr_credite); // removed &s
}

search and edit function no copy paste?

Hi this code is just an example of what im working on. I've got the solution by copying everything from my search function and dump it into my edit function. Is there any better solution rather than just copy pasting?
struct inventory
{
float a,b,c,d;
char something[MAXSIZE];
};
typedef struct inventory Inventory;
struct will contain some float integer and some characters.
void search(const Inventory inv[], int np); // declare search function
void edit(struct inventory inventoryRegister[],int np);
int main(void)
{
int np=0;
struct inventory inventoryRegister[MAXSIZE];
// calling the functions search and edit
search(inventoryRegister, np);
edit(inventoryRegister, np);
return 0;
}
void search(const Inventory inv[], int np)
{
int i,
float min, max;
printf("Enter min max");
scanf("%f %f", &min, &max);
for (i = 0; i < np; i++)
if (inv[i].a >= low && inv[i].a <= high)
{
print..
}
//repeat for b,c,d and something
}
void edit(struct inventory inventoryRegister[],int np)
{
int a;
print("Enter new a");
scanf("%f", &a);
// Here i can copy and paste my entire search function and do a loop to replace the min & max with my new input a.
But is there any easier way to do it? say i call the search(); and somehow extract the elements between min & max and do a loop replacement with a?
Any suggestion?
}
Disclaimer : Its a kind of a psuedo code
struct MinMaxLocation
{
int minloc;
int maxloc;
};
struct MinMaxLocation getMinMaxLocation(struct inventory inventoryRegister[],float min,float max)
{
// your logic to find min and max locations here
struct MinMaxLocation loc;
loc.minloc = // min element location
loc.maxloc = // max element location
return loc;
}
void search(....)
{
struct MinMaxLocation loc_here_search = getMinMaxLocation(inventoryRegister,min,max);
for (i = loc_search_here.min; i < loc_search_here.max; i++)
{
print ...
}
}
void edit(....)
{
struct MinMaxLocation loc_here_search = getMinMaxLocation(inventoryRegister,min,max);
for (i = loc_search_here.min; i < loc_search_here.max; i++)
{
edit the values here ...
}
}

expected expression before 'struct'

I'm getting the error "expected expression before 'struct'" on the the first line in the function allocate() below. I cant figure out why.
I should say that I've been tasked to make this code work with the structure / function headers provided.
Any help is much appreciated!
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <assert.h>
#include <time.h>
struct student{
int id;
int score;
};
struct student* allocate(){
/*Allocate memory for ten students*/
struct student *stud = malloc(10 * sizeof struct *student);
assert (stud !=0);
return stud;
}
void generate(struct student *students){
/*Generate random ID and scores for ten students, ID being between 1 and 10, scores between 0 and 100*/
srand(time(NULL));
// Generate random ID's
int i;
for(i=0; i<10; i++){
students[i].id = rand()*10+1;
}
//Generate random scores
for(i=0; i<10; i++){
students[i].score = rand()*10+1;
}
}
void output(struct student* students){
//Output information about the ten students in the format:
int i;
for(i=0; i<10; i++){
printf("ID-%d Score-%d\n", students[i].id, students[i].score);
}
}
void summary(struct student* students){
/*Compute and print the minimum, maximum and average scores of the ten students*/
int min = 100;
int max = 0;
int avg = 0;
int i;
for(i=0; i<10; i++){
if(students[i].score < min){
min = students[i].score;
}
if(students[i].score > max){
max = students[i].score;
}
avg = avg + students[i].score;
}
avg = avg/10;
printf("Minimum score is %d, maximum score is %d, and average is %d.", min, max, avg);
}
void deallocate(struct student* stud){
/*Deallocate memory from stud*/
free (stud);
}
int main(){
struct student *stud = NULL;
/*call allocate*/
stud = allocate();
/*call generate*/
generate(stud);
/*call output*/
output(stud);
/*call summary*/
summary(stud);
/*call deallocate*/
deallocate(stud);
return 0;
}
You may want to write
sizeof(struct student)
instead of
sizeof struct *student
Your problem is in sizeof struct *student. When using the sizeof operator on a typename, you need to parenthesize the typename. In addition, as Jonathan Leffler identified in the comments to this answer, the placement of * in struct *student is erroneous, and the use of struct student * would be incorrect in the context of this code. Perhaps you meant: sizeof (struct student).
Alternatively, you could use sizeof on an expression, and you won't need the parenthesis. This would be preferable, because if you choose to change the type of stud then you won't need to replace an extra typename when you do so: struct student *stud = malloc(10 * sizeof *stud);

How to sort Struct using qsort in C programming

I have created an array of struct and i would like to sort them using qsort to sort dates chronologically to the string month or i should say char month[]. how can i make the following code display the struct according to a month. please advice. thanks
struct dates
{
int index;
int day;
int year;
char month[15];
};
int i=0;
int count = 0 ;
char test ='\0';
int total =0;
printf("Please enter the number of dates you need to display");
scanf("%d",&total);
struct dates *ip[total];
for(count =0; count< total; count++){
ip[count] = (struct dates*)malloc(sizeof(struct dates));
printf("\nEnter the name month.");
scanf("%s", ip[count]->month);
printf("\nEnter the Day.");
scanf("%d",&ip[count]->day);
printf("\nEnter the Year.");
scanf("%d", &ip[count]->year);
}
for(i=0; i<total; i++){
printf("%s %d %d\n\n",ip[i]->month,ip[i]->day,ip[i]->year);
}
you can define your own comparator to sort http://www.cplusplus.com/reference/clibrary/cstdlib/qsort/
So to sort integers you would use
int intcomp(void *a, void *b){
int *_a = (int *)a;
int *_b = (int *)b;
if(*_a > *_b) return -1;
if(*_a == *_b) return 0;
return 1;
}
I think you can make your own comparator function from that.
There's an example in the man page of qsort
static int
cmp(const void *p1, const void *p2)
{
int y1 = ((const struct dates*)p1)->year;
int y2 = ((const struct dates*)p2)->year;
if (y1 < y2)
return -1;
else if (y1 > y2)
return 1;
/* years must be equal, check months */
...
}
and then
qsort(dates, total, sizeof(*dates), cmp);

Resources