displaying values in c structure array - c

I'm trying to display the values of my structure array, the compiler throws out the following error:
athletes.c:17: error: expected ')' before '*' token
Could someone help me out with a solution and if possible an explanation as to what I did wrong.
#include <stdio.h>
#include <string.h>
struct athlete {
char last_name[25];
char first_name [20];
int rank;
float salary;
};
int main (void) {
struct athlete players[] = {{"Lebron", "James",1,25}, {"Durant", "Kevin",3,20},{"Duncan","Tim",2,12}};
display_jock(players);
}
void display_jock(athlete *p) {
printf ("%10c%10c%10d%10.1f \n", p[0].last_name,p[0].first_name,p[0].rank, p[0].salary);
printf ("%10c%10c%10d%10.1f \n", p[1].last_name,p[1].first_name,p[1].rank, p[1].salary);
printf ("%10c%10c%10d%10.1f \n", p[2].last_name,p[2].first_name,p[2].rank, p[2].salary);
}

there are several small errors:
your code does not know the type "athlete", so your class display_jock should be defined with argument struct athlete: void display_jock(struct athlete *p)
you should forward declare that function: otherwise main doesn't know it (edit:you could also just move the display_jock function at the top of the main function)
when printing a char array, you should use %s instead of %c when using printf.
your main function should return an int (since it is declared as int main...)
this is your code fixed up:
#include <stdio.h>
#include <string.h>
struct athlete {
char last_name[25];
char first_name [20];
int rank;
float salary;
};
void display_jock(struct athlete *p);
int main (void) {
struct athlete players[] = {{"Lebron", "James",1,25}, {"Durant", "Kevin",3,20},{"Duncan","Tim",2,12}};
display_jock(players);
return 0;
}
void display_jock(struct athlete *p) {
printf ("%s%s%10d%10.1f \n", p[0].last_name,p[0].first_name,p[0].rank, p[0].salary);
printf ("%s%s%10d%10.1f \n", p[1].last_name,p[1].first_name,p[1].rank, p[1].salary);
printf ("%s%s%10d%10.1f \n", p[2].last_name,p[2].first_name,p[2].rank, p[2].salary);
}

Related

Most effective way to print the info of a entire structure C?

I want to know if there is a more effective way (less lines, less memory) to print the information contained in the string. I was thinking in a cycle with the funtion argument. For example if you need to print the info(name, group and birthdate) of 100 students, I guess there is a better way that write printstudent( studentn) a hundred times.
The thing is that I dont know how to create a cycle so calls from student1 to student100. I cannot call it student[i] or can I?.
I am open to any kind of suggestions or ideas Thanks!
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
void printstudents(struct st student);
struct st {
char familia[1000];
char imia[1000];
char otchestvo[1000];
int gruppa;
int grozhdenia;
};
int main() {
struct st student1;
struct st student2;
struct st student3;
//Информация студентов:
strcpy(student1.familia, "Putin");
strcpy(student1.imia, "Vladimir");
strcpy(student1.otchestvo, "Vladimirovich");
student1.gruppa = 40040;
student1.grozhdenia = 1952;
strcpy(student2.familia, "Gordon");
strcpy(student2.imia, "Dymitro");
strcpy(student2.otchestvo, "Aleksandrovich");
student2.gruppa = 50050;
student2.grozhdenia = 1953;
strcpy(student3.familia, "Emelianenko");
strcpy(student3.imia, "Fedor");
strcpy(student3.otchestvo, "Olegovich");
student3.gruppa = 60060;
student3.grozhdenia = 1950;
printstudents(student1);
printstudents(student2);
printstudents(student3);
return 0;
}
void printstudents(struct st student) {
printf("Student: %s %s %s, %d, %d \n", student.imia, student.otchestvo,
student.familia, student.gruppa, student.grozhdenia);
}
#include <stdio.h>
#include <string.h>
struct st;
void printstudents(const struct st *student);
struct st {
char familia[1000];
char imia[1000];
char otchestvo[1000];
int gruppa;
int grozhdenia;
};
int
main(void)
{
struct st student[3] = {
{ "Putin", "Vladimir", "Vladimirovich", 40040, 1952 },
{ "Gordon", "Dymitro", "Aleksandrovich", 50050, 1953 },
{ "Emelianenko", "Fedor", "Olegovich", 60060, 1950}
};
for( int i = 0; i < 3; i ++ ){
printstudents(student + i);
}
return 0;
}
void
printstudents(const struct st * student)
{
printf("Student: %s %s %s, %d, %d\n",
student->imia,
student->otchestvo,
student->familia,
student->gruppa,
student->grozhdenia
);
}
If we are talking actual performance in terms of execution speed and memory use, then here are the most obvious bottlenecks:
printf with its format string parsing is slow. It is likely quite a bit faster to use repeated puts calls than a single printf.
Obviously you shouldn't be passing your huge structs by value to the function. struct st student leads to a several kb large struct getting copied to the stack, in case your compiler fails to inline the function call. As a rule of thumb, never pass structs by value. Use pointers.
You make hard copies of constant string literals. You could have just used const char* familia and then do student2.familia = "Gordon"; which is much faster than strcpy. The down-side is that you only get read-only memory if you do like this.
Here's a reworking of your code to use a statically stack-allocated array of 3 student structures (and a helper function to initialize students).
You will need to read up on how pointers work to make sense of it, but that's C for you.
#include <stdio.h>
#include <string.h>
struct st {
char familia[1000];
char imia[1000];
char otchestvo[1000];
int gruppa;
int grozhdenia;
};
static void assign_student(struct st *student, const char *familia, const char *imia, const char *otchestvo, int gruppa, int grozhdenia) {
// TODO: use strncpy
strcpy(student->familia, familia);
strcpy(student->imia, imia);
strcpy(student->otchestvo, otchestvo);
student->gruppa = gruppa;
student->grozhdenia = grozhdenia;
}
static void print_student(struct st *student) {
printf("Student: %s %s %s, %d, %d \n", student->imia, student->otchestvo,
student->familia, student->gruppa, student->grozhdenia);
}
int main() {
struct st students[3];
assign_student(&students[0], "Putin", "Vladimir", "Vladimirovich", 40040, 1952);
assign_student(&students[1], "Gordon", "Dymitro", "Aleksandrovich", 50050, 1953);
assign_student(&students[2], "Emelianenko", "Fedor", "Olegovich", 60060, 1950);
for (int i = 0; i < 3; i++) {
print_student(&students[i]);
}
return 0;
}

How to correctly pass structures to functions

So the question I'm working on has me creating a structure with 5 elements: id number, name, department, course, and year. I have to write a function that prints the names of people with certain years and a function that prints all data based on id number input.
When I type in 2020 as an input I get a segmentation fault. What could be causing this?
#include <stdio.h>
struct stud
{
int id;
char name[50];
char dep[50];
char course[50];
int year;
};
void printbyyear(struct stud *student,size_t sz, int a);
void printspecific(struct stud *b,size_t sz, int a);
int main()
{
int yr,num,b;
struct stud students[]={
{1,"Jon","math","calc",2019},
{2,"Tim","Language arts","calc",2020},
};
printf("Input year to search for:");
scanf("%d",&yr);
printbyyear(students, sizeof(students),yr);
printf("Input ID # to search for:");
scanf("%d",&num);
printspecific(students, sizeof(students),num);
return 0;
}
void printbyyear(struct stud *b,size_t sz, int a)
{
int i;
for(i=0;i<sz;i++)
{
if (b[i].year==a)
{
printf("%d %c %c %c %d",b[i].id,b[i].name,b[i].dep,b[i].course,b[i].year);
}
}
}
void printspecific(struct stud *b,size_t sz, int a)
{
printf("%d %c %c %c %d",b->id,b->name,b->dep,b->course,b->year);
return 0;
}```
There are many mistakes in your programs.
printbyyear(struct stud,yr);
that is not how you call a function with struct variable, change it as printbyyear(b1,yr); or printbyyear(b2,yr);
you are not using array of structs , so you don't need to use loops at all for your code.
if (b.year == a)
{
printf("%d %s %s %s %d",b.id,b.name,b.dep,b.course,b.year);
}
finally if you want to store multiple records, then use array of struct's like below.
struct stud students[]= {
{2,"Tim","Language arts","calc",2020},
{1,"Jon","math","calc",2019}
};
and call it as below ( sizeof(students)/sizeof(students[0]) ) gives the number of elements you have in your structure)
printbyyear(students, sizeof(students)/sizeof(students[0]), yr);
now you can use loops for printing because you passed an array
void printbyyear(struct stud *student, size_t sz, int y)
{
int i;
for(i=0;i<sz;i++)
{
if (student[i].year == y)
{
printf("%d %s %s %s %d",student[i].id,student[i].name,student[i].dep,student[i].course,student[i].year);
}
}
}
and you declaration of function should be as below
void printbyyear(struct stud *b,size_t size, int a);
I guess that here
if (b[i]stud.year==a)
You are trying to access b1, b2 and any other possible student. To do that you need an array of type struct stud
struct stud b[5];
Now your if condition makes sense. The function call should be:
printbyyear(b,yr);
And the declaration
void printbyyear(struct stud *b, int a)
Also since you initialize only two students, i.e. only two elements of your array, the for loop should be for(i=1;i<=2;i++) with a 2 not a 5.
Accessing uninitialised elements or accessing an array out of bounds will result in an undefined behaviour.
Correct is an ambiguous term, so I will just say this method is one that I prefer:
Passing the address of an object of significant size is advantageous in that the address of that object is going to be smaller than the object itself.
So given for example your struct (typedefed for readability) I would make the following modifications (i.e. to pass by reference to the address of the object.)
Read in-line comments and note corrections in code:
typedef struct
{
int id;
char name[50];
char dep[50];
char course[50];
int year;
}stud_s;
//modify to accept pointer, and add size of array argument
void printbyyear(stud_s *s, int yr, size_t size);
int main()
{
int yr,num;
stud_s b1[] = { {1,"Jon","math","calc",2019},
{2,"Tim","Language arts","calc",2020},
{3,"Jen","the arts","calc",2021},
{4,"Bob","painting arts","calc",2022},
{5,"jed","numeric arts","calc",2023}
};
size_t size = sizeof(b1)/sizeof(b1[0]);
printf("Input year to search for:");
scanf("%d",&yr);
printbyyear(b1,yr, size);// b1 is a pointer to array of struct here.
printf("Input ID # to search for:");
scanf("%d",&num);
return 0;
}
void printbyyear(stud_s *b, int a, size_t size)
{
int i=0;
//for(i=1;i<=5;i++)//results in out of bounds access to array
for(i=0;i<size;i++) //change magic number for actual size of array
{
if (b[i].year==a)
{
//fix format specifiers
printf("%d %s %s %s %d\n",b[i].id,b[i].name,b[i].dep,b[i].course,b[i].year);
//printf("%d %c %c %c %d",b[i].id,b[i].name,b[i].dep,b[i].course,b[i].year);
i++;
}
}
}

Having trouble with char pointers

I'm having trouble with char pointers. I'm trying to get the value from the store_stuff function and print it into the main function. How can I do this?
#include <stdio.h>
#include <string.h>
#include <assert.h>
void store_stuff(char *name, int *age);
int main(void) {
char *name;
int age;
store_stuff(&name, &age); // I'm having trouble here
printf("Name: %s\n", name);
printf("Age: %d\n", age);
}
void store_stuff(char **name, int *age) {
*name = "John";
*age = 31;
}
https://ideone.com/5HOPGQ
#include <stdio.h>
#include <string.h>
#include <assert.h>
char *store_stuff(char **name, int *age);
int main(void) {
char *name;
int age;
store_stuff(&name, &age); // I'm having trouble here
printf("Name: %s\n", name);
printf("Age: %d\n", age);
}
char *store_stuff(char **name, int *age) {
*name = "John";
*age = 31;
return *name;
}
Make it
void store_stuff(char** name, int* age)
{
*name = "John";
*age = 31;
}
You need that pointer to a pointer for name assignment to make its way out of store_stuff
Also you need to change your definition of
char name
to
char* name
Since name itself wants to be a pointer to interact as a string
EDIT: And of course, be sure to make your prototype consistent at the top with void store_stuff(char** name, int* age);

Struct not retaining data when passed as a pointer

I've defined a header file with a struct and function prototypes that take a pointer to a struct as a parameter. The code compilation goes fine except that struct instantiated in the main do not seem to retain numerical data.
This is the header file:
#ifndef _GETDATA
#define _GETDATA
#include <stdio.h>
struct PERSONDATA{
char name[20];
double age,mass;
};
typedef struct PERSONDATA person;
extern void getData(person *);
extern void getName(char *,int);
#endif
This is the getData.c file:
#include <stdio.h>
#include "GETDATA.h"
void getData(person *ptr)
{
printf("Enter name: ");
getName(ptr->name,sizeof(ptr->name));
printf("enter age: ");
scanf("%f",&(ptr->age));
printf("enter mass: ");
scanf("%f",&(ptr->mass));
}
and this is the getName.c file:
#include <stdio.h>
#include "GETDATA.h"
void getName(char *ptrName, int varSize)
{
int i=0;
do
{
*(ptrName++) = getchar();
++i;
if(i==varSize) printf("array full, EXITING!\n");
}while(*(ptrName-1)!='\n' && i<varSize);
*(ptrName-1) = '\0';
}
The main function is as follows:
#include <stdio.h>
#include "GETDATA.h"
int main(int argc, char **argv)
{
person human1;
printf("hello, world!\n\n");
getData(&human1);
printf("\nData entered: \n");
printf("\tname = %s\n",human1.name);
printf("\tMass = %f\n",&(human1.mass));
printf("\tAge = %f\n",&(human1.age));
return 0;
}
This is the console output when the code is run:
What could be going wrong here?
Your values are doubles, not floats. You need to use %lf with scanf():
printf("enter age: ");
scanf("%lf",&(ptr->age));
printf("enter mass: ");
scanf("%lf",&(ptr->mass));
Also, your prints are wrong. You are passing a pointer. It should be
printf("\tMass = %f\n",human1.mass);
printf("\tAge = %f\n",human1.age);

Error while executing: Segmentation fault

I'm a beginner in C language. After reading the initial chapters of Ritchie's book, I wrote a program to generate random numbers and alphabets.
The program compiles fine with gcc. However on running it, it gives an error "Segmentation fault", which is incomprehensible to my limited knowledge. I'd be glad to understand what I've written wrong.
#include <stdio.h>
#include <stdlib.h>
#include "conio.h"
#include <time.h>
long int genrandom(int,int);
void randAlph(void);
char letterize(int);
int main (void) {
// char full[9];
// char part_non[4];
srand(time(0));
int i;
for (i=0;i<50;++i) {
randAlph();
};
}
long int genrandom(int mino,int maxo) {
int val=mino+rand()/(RAND_MAX/(maxo-mino)+1);
return val;
}
void randAlph (){
int val;
char text;
val=genrandom(0,26);
// return val;
text=letterize(val);
printf("%s ,",text);
}
char letterize(int num) {
char letter='A'+num;
return letter;
}
printf("%s ,",text); is wrong - it says that text is a nul-terminated array of chars. Use
printf("%c ,", text);
instead to print your single char.
#include <stdio.h>
#include <stdlib.h>
#include "conio.h"
#include <time.h>
int genrandom(int,int);
void randAlph(void);
char letterize(int);
int main (void) {
// char full[9];
// char part_non[4];
srand(time(0));
int i;
for (i=0;i<50;++i) {
randAlph();
};
}
int genrandom(int mino,int maxo) {//changed function return type to int
int val=mino+rand()/(RAND_MAX/(maxo-mino)+1); //Be careful when you are using '/' operator with integers
return val; //returning int here why set return type to long int?
}
void randAlph (){
int val;
char text;
val=genrandom(0,26);
// return val;
text=letterize(val);
printf("%c ,",text);//Replace %s with %c
}
char letterize(int num) { //No bound checking on num eh?
char letter='A'+num;
return letter;
}
That's all I had to say. :)
Why use %s when text is char. You dont need a string type in the function. Just a char would do. Change in the function : void randAlph ()
printf("%s ,",text);
to
printf("%c ,", text);

Resources