Accessing struct array outside function - c

..C..
I am trying to figure out how to access my filled array which utilizes a struct with another function which I will use later for sorting, but I can't even print my function that filled the array in my main.
I have loaded the function inside main which works and printing inside the fillArray function works but I will need to access the array from outside the function later on for a bubble sort and a binary search.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#define SIZE 100
typedef struct Person
{
char firstname[25];
char lastname[25];
} person;
person list [SIZE];
person loadPeople(char firstname[25],char lastname[25])
{
person p;
strcpy(p.firstname, firstname);
strcpy(p.lastname, lastname);
return p;
}
void fillArray()
{
list[0] = loadPeople("Bob","Baker");
list[1] = loadPeople("Bill","Johnson");
list[2] = loadPeople("John","Finmeister");
list[3] = loadPeople("Jennifer","Ratblaster");
list[4] = loadPeople("Shaun","Gares");
list[5] = loadPeople("Diggy","McDigMaster");
list[6] = loadPeople("Joanne","TheStore");
}
int main(int argc , char *argv[])
{
printf("First homie's name is: %s %s\n",list[0].firstname,list[0].lastname);
return 0;
}
I just want to print from main recalling from fillArray but right now it only prints:
First homie's name is:
thats it

You need to call fillArray() in order to execute it:
int main(int argc , char *argv[])
{
fillArray();
printf("First homie's name is: %s %s\n",list[0].firstname,list[0].lastname);
return 0;
}
Note that main() should only have two parameters as shown here.

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

Allocating memory for a struct variable using a function

As part of a larger project, I am trying to write a function that will allocate enough memory for a struct variable and assign values to its member variables after scanning them from the keyboard. In other words, I am trying to create a sort of a constructor function. The reason for this is because I think that's the best way to create a database-like program in c, where all the student_t variables will be stored in a student_t* array called classroom.
#include <stdio.h>
#include <stdlib.h>
#define N 10
#define STRLIM 50
typedef struct student{
char* name;
int age;
}student_t;
student_t* init_student(student_t* s);
int i=0;//its the array counter
student_t* classroom[N];
int main(int argc, char const *argv[]){
while(i<N){
// classroom[i]=(student*)malloc(sizeof(student));
init_student(classroom[i]);
classroom[i]->age=i;
printf("The age of student #%d is : %d \n",i,classroom[i]->age);
printf("the name of student #%d is : %s",i,classroom[i]->name);
i++;
}
printf("the size of the classroom is : %ld",sizeof(classroom));
return 0;
}//end of main()
student_t* init_student(student_t* s){
s=(student_t*)malloc(sizeof(student_t));
s->name=(char*)malloc(sizeof(char)*STRLIM);
fflush(stdin);
fgets(s->name,STRLIM,stdin);
return s;
}
Gdb ouput shown in the attached image here.
Please check out my repo.
I am guessing something about my build and datatypes is off .Thanks in advance.

How do I print elements of structures contained in an array

I have created an array of structure as a global variable. I initialised the array in a function and I could print out the elements of the structure from there. My problem is that I can't print out values of the array in another function( main() in my case) other than the one I used to initialise the array. Please how can I print those values? Thank you.
#include <stdio.h>
#include <stdlib.h>
/*
*
*/
typedef struct s{
char *value;
} S;
S list[2];
void function( ){
char val1[] = "val1";
char val2[] = "val2";
S v1 = {val1};
S v2 = {val2};
list[0] = v1;
list[1] = v2;
printf("%s\n", list[1].value); //prints val2
}
int main(int argc, char** argv) {
function();
printf("%s", list[1].value); //prints nonsense
return 0;
}
What I have tried :
I modified function() to take list as an argument( function (list)) and declared list in main() instead. It didn't work.
I modified function to return list (S* function()), it didn't work.
I used an array of integers ( instead of structure i.e. int list[2], declared it as a global variable and initialised it in function()) and everything worked fine, suggesting that the problem is from how I am accessing structure, but I just can't figure it out.
I searched the internet, but couldn't get a similar problem.
In your function function you assign an address of a local variable to your structure. After returning from function this address is no longer valid. You could either make it static or allocated it dynamically.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct s
{
char *value;
} S;
S list[2];
void function( )
{
char val1[] = "val1";
char val2[] = "val2";
//Note that you are creating a copy of "val1" here which can be avoided by changing it to char *val1 = "val1";
list[0].value = malloc(strlen(val1)+1); //allocate space for val1 + NUL-terminator
strcpy(list[0].value, val1); //copy string
list[1].value = malloc(strlen(val2)+1);
strcpy(list[1].value, val2);
//You could also use the function strdup which allocates memory and duplicates the string
//list[0].value = strdup(val1);
printf("%s\n", list[1].value); //prints val2
}
int main(int argc, char** argv)
{
function();
printf("%s", list[1].value);
free(list[0].value); //Don't forget to free.
free(list[1].value);
return 0;
}

creating, passing, getting back Array of a Struct and loop throuh it in C

I need to execute a function that returns array of a specified struct with variable length. Then I should loop through the returned array.
example struct :
typedef struct student {
int id;
char *name;
int grade;
} Student;
function prototypes 1 :
Student *students;
students = findStudentByGrade(int grade);
function prototypes 2 :
Student *students;
int retval = findStudentByGrade(&students, int grade);
I am bit confused on above methods. How can correctly define a array of struct? call function ? and loop through it untill end? Can some one help me please.
You can do this in this way. This code is working. I tested in CodeLite.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef struct student {
int id;
char *name;
} Student;
Student *findStudent(int *asize, const int grade);
int main(void)
{
Student *stds;
int asize = 0;
stds = findStudent(&asize, 5);
int i;
for (i = 0; i < asize; i++) {
printf("ID : %i\n", stds[i].id);
}
return 0;
}
Student *findStudent(int *asize, const int grade)
{
struct student *stds = malloc(sizeof(struct student) * 3);
stds[0].id = 10;
stds[1].id = 20;
stds[2].id = 40;
*asize = 3;
return stds;
}
Get the array of struc as returned statement and pass an int variable with argument list to get the size back and simply loop through using a for loop. Or else you will find problem in looping. It is more easy to get the array size from the function which create the array.
I mean this is quite a basic question, but:
Defining array of your structures would look like:
int size = ...;
Student *students = (Student*) malloc(sizeof(Student) * size);
Then just pass that to the function (both size and the array) and then just loop until i < size.
Ofcourse, don't forget to:
free(students);
at the end.

Instantiations for structs in C?

So I'm trying to learn C right now, and I have some basic struct questions I'd like to clear up:
Basically, everything centers around this snippet of code:
#include <stdio.h>
#include <stdlib.h>
#define MAX_NAME_LEN 127
const char* getName(const Student* s);
void setName(Student* s, const char* name);
unsigned long getStudentID(const Student* s);
void setStudentID(Student* s, unsigned long sid);
int main(void) {
Student sarah;
const char* my_name = "Sarah Spond";
setName(&sarah, my_name);
printf("Name is set to %s\n", sarah.name);
}
typedef struct {
char name[MAX_NAME_LEN + 1];
unsigned long sid;
} Student;
/* return the name of student s */
const char* getName (const Student* s) { // the parameter 's' is a pointer to a Student struct
return s->name; // returns the 'name' member of a Student struct
}
/* set the name of student s
If name is too long, cut off characters after the maximum number of characters allowed.
*/
void setName(Student* s, const char* name) { // 's' is a pointer to a Student struct | 'name' is a pointer to the first element of a char array (repres. a string)
int iStringLength = strlen(name);
for (i = 0; i < iStringLength && i < MAX_NAME_LEN; i++) {
s->name[i] = name[i];
}
}
/* return the SID of student s */
unsigned long getStudentID(const Student* s) { // 's' is a pointer to a Student struct
return s->sid;
}
/* set the SID of student s */
void setStudentID(Student* s, unsigned long sid) { // 's' is a pointer to a Student struct | 'sid' is a 'long' representing the desired SID
s->sid = sid;
}
However, when I try and compile the program, I get a bunch of errors saying that there's an "unknown type name Student". What am I doing wrong?
Thanks!
Move the type definition for Student - the typedef .. right after #define MAX_NAME_LEN 127, i.e. before it's being referenced.
You need to move the declaration of the Student struct above the first time it is referenced by other code - otherwise those functions will not know what it is.
Struct declarations need to be defined before you use them , so you need to move your Student
As cnicutar said, move the typedef - the reason for this is that the type must be known before it's used. Alternatively, you can forward declare the type.
> Move the typedef .. right after #define MAX_NAME_LEN 127, i.e. before
> it's being used.
OR, if you want to keep your definition after, and if you are ready to use a pointer to Student, you can:
#include <stdio.h>
#include <stdlib.h>
#define MAX_NAME_LEN 127
// forward declare Student ici
struct Student;
//...
// in main, use a pointer to student
int main(void) {
Student *sarah; // Changed to pointer
const char* my_name = "Sarah Spond";
setName(sarah, my_name); // Pass the pointer instead of reference
printf("Name is set to %s\n", sarah->name); // Use the pointer
//....
delete sarah; // delete object when done
}
// Change struct decl to the following // can't explain the diff yet
struct Student {
char name[MAX_NAME_LEN + 1];
unsigned long sid;
};
A basic structure of a C program is:
//======DOCUMENT SECTION=========
//File:test.c
//Author:
//Description:
//...
//================================
//====INCLUDE SECTION=============
#include "lib1"
#include <lib2>
//================================
//========DEFINITIONS SECTION=====
#define TRUE 1
#define FALSE 0
//================================
//========STRUCTURES SECTION======
struct P{
};
//================================
//========TYPEDEFS SECTION========
typedef *P P;
//================================
//========FUNCTION HEADERS========
void foo1(...);
int foo2(...,...,...);
//================================
//=========GLOBAL VARIABLES=======
int GLOBAL_INT;
float GLOBAL_FLOAT;
//================================
//=====MAIN FUNCTION DEFINITION===
void main(void)
{
...
...
...
}
//=================================
//======FUNCTIONS DEFINITION======
void foo1(...)
{
}
int foo2(...,...,...)
{
}
//================================
A main function is where a C program starts. A main function also typically has access to the command arguments given to the program when it was executed.
Usually you have got:
int main(void);
int main();
int main(int argc, char **argv);
int main(int argc, char *argv[]);

Resources