How to swap the order of array in a struct? - arrays

struct student{
char firstname[100];
char lastname[100];
int age;
float credit;
}s[2];
int main() {
int i,j;
printf("Students information\n");
// program that allocates the information
for(i=0;i<2;i++){
printf("Enter full name:");
scanf("%s",s[i].firstname);// scans the name
scanf("%s",s[i].lastname);// scans the name
printf("Age:");
scanf("%d",&s[i].age); // scans the age
printf("Credit:");
scanf("%f",&s[i].credit);
}
// sorting in order of ages
int rep,temp,res;
char name1[100], lname[100];
float cred;
for(i=0;i<2;i++){
for(j=1;j<2;j++){
if(s[i].age < s[j].age){
temp=s[i].age;
s[i].age=s[j].age;
s[j].age= temp;
cred=s[i].credit;
s[i].credit=s[j].credit;
s[j].credit=cred;
}
}
}
// displaying stored information
printf("Name\t\t\tAge\t\t\tCredits Earned\n");
for(i=0;i<2;i++){
printf("%s %s\t\t",s[i].firstname, s[i].lastname);
printf("%d\t\t%.2f",s[i].age, s[i].credit);
printf("\n");
}
return 0;
}
I am trying to sort the first and last name in alphabetical order. While I have figured out how to change the order for the age and credit, it seems as if I cannot use bubble sort to switch the first and last name because they are character array. I have to do this using struct and I have to print three tables. I was wondering if there was any other way I could do the whole thing.

Related

When printing array of structs, getting ascii symbols and no names or values

I am not sure if this issue is born from my input of info into the struct, or my printing routine.
My code looks like this:
struct srecord {
char name[15];
int score;
};
void getAScore(struct srecord r, char name[], int scores){
strcpy(r.name,name);
r.score = scores;
}
void getScores(struct srecord students[], int* num ){
printf("Enter number of students and then those students names and scores separated by a space.\n");
scanf("%d", num);
int i;
char names[15];
int scores;
int j;
for(i = 0; i < *num; i++){
scanf("%s%d", names, &scores);
getAScore(students[i], names, scores);
}
}
void printAScore(struct srecord r){
printf("%s%d\n", r.name, r.score );
}
void printScores(struct srecord r[],int num){
int i;
for(i = 0; i < num; i++){
printAScore(r[i]);
}
}
As you can see the struct is comprised of a name array, and score. We create 10 of these structs in an array in the main class.
int main(){
struct srecord students[10]; // can handle up to 10 records
int num; // number of students
int average;
getScores(students, &num);
printScores(students, num);
I have to input all of the info at once in the terminal, and then print it out exactly the same.
So I put an input like this, where the first line is the number of students, and each subsequent line is a name followed by a score, like so:
3
Tom 90
Jones 78
lawrence 8
However, when I go to print it I get this:
#0
0
0
I believe my pointers are correct, but I assume that the info is being put incorrectly into the array of structs?
I've been fooling around with the loops, but nothing important has changed, and nothing is really working, so I am just sort of lost with this right now. I looked up the manual for structs and printf and scanf, but nothing really stuck out to me as to what may be the issue, nor have other threads on the topic.
getAScore() needs to receive a pointer to the structure so it can modify it. Otherwise it's modifying a local copy that goes away when the function returns.
It also needs to copy the name into the structure.
void getAScore(struct srecord *r, char name[], int scores){ strcpy(r.name,name);
r->score = scores;
strcpy(r->name, name);
}
Then change the call to:
getAScore(&students[i], names, scores);

use printf and scanf on char *

I'm having problems inputting values into this structure template, please help.
I've got to use char* for those attributes. so it doesn't give an error while inputting data but crashes when its time to display.
#include<stdio.h>
#include<malloc.h>
#include<conio.h>
struct Date
{
int day;
char *month;
int year;
}date;
struct sports_team
{
char *name;
char *city;
int no_of_players;
struct Date creation_date;
};
void main()
{
struct sports_team *my_team;
my_team = (struct sports_team*)malloc(sizeof(struct sports_team)*2);
printf("fill information for teams:\n");
for(int i=0;i<2;i++)
{
printf("\nenter team name:");
scanf("%s",&my_team[i].name);
printf("\nenter team city:");
scanf("%s",&my_team[i].city);
printf("\nenter no. of players:");
scanf("%d",&my_team[i].no_of_players);
printf("\nenter creation day:");
scanf("%d",&(my_team[i].creation_date.day));
printf("\nenter creation month:");
scanf("%s",&(my_team[i].creation_date.month));
printf("\nenter creation year:");
scanf("%d",&(my_team[i].creation_date.year));
printf("\n\n");
}
printf("\n information for teams:\n");
for(int i=0;i<2;i++)
{
printf("%s ",my_team[i].name);
printf("%s ",my_team[i].city);
printf("%d ",my_team[i].no_of_players);
printf("%d ",my_team[i].creation_date.day);
printf("%s ",my_team[i].creation_date.month);
printf("%d ",my_team[i].creation_date.year);
printf("\n\n");
}
free(my_team);
}
you're allocating the structures all right but you're forgetting to allocate memory for char * members: you're writing into uninitialized memory when doing scanf (not to mention that you're passing the address of the pointer, not the pointer itself: don't use & when scanning strings).
For simplicity's sake, you could just put fixed buffer lengths in your structures:
struct Date
{
int day;
char month[20];
int year;
}date;
struct sports_team
{
char name[100];
char city[100];
int no_of_players;
struct Date creation_date;
};
and limit size when scanning (don't use & when scanning strings BTW)
scanf("%99s",my_team[i].name);
scanf("%99s",my_team[i].city);
scanf("%19s",my_team[i].creation_date.month);
Use getchar() instead of scanf().

writing to strings inside a structure doubly linked list in C

I have an issue with my code, I changed a few of the functions to accomodate the structure I added, so instead of having variables all over the place, but now it does not work at all. I need it to create a structure person, then it prompts the user to enter the persons name, and age; then it asks for more persons to fill a doubly linked list which stops the loop if nothing is input for the persons name. THEN it spits out the reverse of what I input into the doubly linked list. All help is appreciated ^-^
struct person
{
char name[10][41];
int age[10];
};
int write(struct person *people);
void print(struct person *people);
int main(void)
{
char names[10][41];
int n = 10;
int ages[10];
typedef struct person people;
n = write(people);
print(people);
system("PAUSE");
return 0;
}
int write(struct person *people)
{
int i;
char name[41];
int age[10];
for(i=0; i<=i; i++)
{
fflush(stdin);
printf("Enter full name\n");
gets(people.name);
strcpy(names[i], name);
if(names[i][0] == '\0')
break;
printf("Enter their age\n");
scanf("%d", &age[i]);
ages[i] = age[i];
}
}
void print(struct person *people)
{
int i = 0;
for(i = 0; i < 10; i++)
{
if(names[i][0] == '\0')
break;
printf("%s is %d year(s) old\n", names[i], ages[i]);
}
return i;
}
You are passing the name of a type that you just defined instead of a variable declared of that type, this
typedef struct person people;
should be
struct person people;
Change
n = write(people);
to
n = write(&people);
Remove fflush(stdin) it's undefined behavior.
Do not use gets() it's very unsafe, use fgets() instead
char name[40];
gets(name);
should be
char name[40];
fgets(name, sizeof(name), stdin);

Pointer to an array of structures

I'm currently trying to write a program for a student database assignment. After manually setting 3 elements of the structure array, the next 3 students' details are inputted by the user.
I am trying to write a function that finds the oldest age of the 6 students and returns it as a student_t entry at index max. I'm struggling with how to actually give the function the pointer that is pointing to the first element of the array stdt[6] and then using the pointer within the function. I also have no idea how I would go about returning to main the entry that has the highest age. If I'm trying to say that the value of an element of array of structures is equal to some other integer (max), doesn't that mean that max is now some other block of memory with an integer value and not linked to the array? So I'm not sure how I would return the entry that has the highest age after the function determines the max age.
This is all I've written so far:
#include <stdlib.h>
#include <stdio.h>
typedef struct {
char *name;
char *surname;
char *UUN;
char *department;
char gender;
int age;
}student_t;
student_t findOldest(student_t *studentarr, int len){
int i;
int x;
int max;
max=0;
for(i=0;i<len;i++){
(p+i).age=x;
if(x>max){
x=max;
}
}
}
int main() {
int i;
student_t stdt[6]={{"John","Bishop","s1234","Inf",'m',18},{"Lady","Cook","s2345","Eng",'f',21},{"James","Jackson","s33456","Eng",'m',17}};
student_t *p=&stdt[0];
for(i=3;i<6;i++) {
printf("First name: \n");
scanf("%s",stdt[i].name);
printf("Last name: \n");
scanf("%s",stdt[i].surname);
printf("UUN: \n");
scanf("%s",stdt[i].UUN);
printf("Department: \n");
scanf("%s",stdt[i].department);
printf("Gender (m/f): \n");
scanf("%c",stdt[i].gender);
printf("Age: \n");
scanf("%d",stdt[i].age);
}
findOldest(p,6);
return 0;
}
This should work.
student_t findOldest(student_t *p, int len){
int i;
student_t max = *(p+0);
for(i=1;i<len;i++)
{if((*(p+i)).age > max.age)
max = *(p+i);
}
return max;
}
You want to return the student so keep the student in your max variable not the age. And to refer to pointers either use
(p+i)->age > max.age
or use
(*(p+i)).age > max.age
But there are other problems with the code.

What's wrong with using pointer in a struct when passing it to gets()?

I have the following code. In the struct definition, I try to ask user to enter employee's first and last name. But when I run this exe, it exit after the title is entered. Any suggestions?
#include<stdio.h>
#include<string.h>
#define NUMEMPS 10
struct Employee {
char *firstname;
char *lastname;
char *title;
int salary;
};
int main()
{
struct Employee* stuff = malloc(NUMEMPS* sizeof *stuff);
int n,i;
for (n=0; n<NUMEMPS;n++)
{
printf("Please enter number %d Employee's Last name:", n);
fflush(stdout);
gets(stuff[n].lastname);
if (strlen(stuff[n].lastname) == 0)
break;
printf("Please enter number %d Employee's first name:", n);
fflush(stdout);
gets(stuff[n].firstname);
printf("Please enter number %d Employee's title:", n);
fflush(stdout);
gets(stuff[n].title);
printf("Please enter number %d Employee's salary:", n);
fflush(stdout);
scanf("%d", &stuff[n].salary);
getchar();
}
for (i = 0;i<n;i++)
{
printf("{%s,%s,%s,%d}\n",
stuff[i].lastname,
stuff[i].firstname,
stuff[i].title,
stuff[i].salary);
}
return 0;
}
The three char* members of the structure are pointers, so no space is allocated to hold any data.
With the current struct you'd have to do three more allocs for the data:
struct Employee* stuff = malloc(NUMEMPS* sizeof *stuff);
stuff->firstname = malloc(101);
stuff->lastname = malloc(101);
stuff->title = malloc(101);
What you probably want is something like:
struct Employee {
char firstname[101];
char lastname[101];
char title[101];
int salary;
};
Also, though as an aside, you must check your malloc calls for a NULL return.
This code:
struct Employee {
char *firstname;
char *lastname;
char *title;
int salary;
};
...
struct Employee* stuff = malloc(NUMEMPS* sizeof *stuff);
only allocates enough room to store a single struct Employee, that is: three pointers and an integer. There's no storage for the character strings pointed to.
Instead, consider malloc()ing each of the constituent character data and assigning to stuff->firstname (et al), or modify the declaration of struct Employee to include character arrays.

Resources