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[]);
Related
hello
I have a two-dimensional array of the string type, but I need to store a number and a string, how could I do this in c language?
#include <stdio.h>
#include <string.h>
#define A 10
#define B 10
string sales[A][B];
int main(void)
{
string product = "A";
int age = 20;
sales[0][1] = {'product', age};
printf("Sales: %s\n", sales[0][1]);
}
Thank You
Use a struct to store a number and a string.
#include <stdio.h>
#include <string.h>
#define A 10
#define B 10
typedef char *string;
struct {
string product;
int age
} sales[A][B];
int main(void)
{
string product = "A";
int age = 20;
sales[0][1].product = product;
sales[0][1].age = age;
printf("Sales: %s\n", sales[0][1].product);
}
string is not a type in C, maybe you are refering to CS50, and in that case it's just a typedef of char*.
In C you can't have an array of different types, the next best thing I can think of is for you to use a structure where you can store both values associated with each other:
typedef struct { // structure to hold data
char product[128]; // char array instead of pointer
int age;
}Sales;
Sales sales[A][B]; // structure array declaration
int main(void)
{
char product[] = "A";
int age = 20;
sales[0][1].age = age;
strcpy(sales[0][1].product, product); // here copying the data instead of pointer
printf("Sales: %s - %d\n", sales[0][1].product, sales[0][1].age);
}
You could use pointers instead of char arrays like Barmar did, and that's a good solution for this particular example, but be aware that pointers can become dangling if the lifetime of the data they point to expires.
i have 2 structs, i want to assign one struct to another, but when i print the results, it prints crap, the functions : "ver_tope" is on charge to do that , what am i doing bad?, here is the code:
#include <stdio.h>
#include <stdlib.h>
#define TAM 4
typedef struct{
char nomyap[40];
int edad;
}t_info;
typedef struct {
t_info pila [TAM];
int tope;
}t_pila;
void ver_tope(const t_pila *p, t_info *d);
int main()
{
t_pila pila;
t_info info;
//I CHARGE BOTH STRUCTS
ver_tope(&pila, &info);
return 0;
}
void ver_tope(const t_pila *p, t_info *d)
{
*d = p->pila[(p->tope)-1];
return ;
}
Try adding an initialisation for pila.tope in main() ex:
... //I CHARGE BOTH STRUCTS
pila.tope =2;
ver_tope(&pila, &info);
...
That stopped the segmentation fault...
int main()
{
t_pila pila;
t_info info;
ver_tope(&pila, &info);
return 0;
}
You have not initialized either variable. Since pila is the source of the assignment you can do the following:
int main()
{
t_pila pila = { 0 };
pila.tope = 1;
t_info info;
ver_tope(&pila, &info);
return 0;
}
Here I default initialized pila and then set its tope member to 1. I did not initialize info since ver_tope assigns to it. It would be clearer if you converted ver_tope into a function that returned t_info.
I know the code below is not complete. I'm debugging it as I go and no matter what I do, I can't figure out why I get error: request for member 'gpa' in something not a structure or union (line 22). I'm positive there is more to be done with the code and that there are more warnings and errors, I'm not worried about those yet. Just this one I have never encountered before.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#define MAXNAME 11
#define MAXSTUDENTS 9
typedef struct student
{
char name[ MAXNAME ];
double gpa;
char grade;
}student_t;
void grade_students(student_t *, int n);
void print_students(student_t *, int n);
int main()
{
student_t students[ MAXSTUDENTS ];
int n;
students.gpa = n;
FILE *infilep;
infilep = fopen("lab09.in", "r");
}
What I am trying to do is use the typedef members but when I try to follow the format used in my text and classnotes, I get the error.
Variable students is declared as an array of elements of type student_t
student_t students[ MAXSTUDENTS ];
So to access an element of the array you should use the subscript operator as for example
students[0].gpa = 0.0;
Another example can be used in function print_students. Though in the function it is just a pointer nevertheless you can use the same syntax with the subscript operator
void print_students( const student_t *students, int n )
{
for ( int i = 0; i < n; i++ )
{
puts( students[i].name );
//...
}
}
I have the following code in C:
typedef struct
{
int age;
int phoneNumber;
} Student;
typedef struct
{
int id;
int student[1];
} People;
#define NUM_OF_PEOPLE
void *p = malloc(sizeof(People) + sizeof(int) * NUM_OF_PEOPLE + sizeof(Student) * NUM_OF_PEOPLE);
How could I find the pointer to the memory point to the first element of struct Student in the memory?
I try to do it in the following way:
int i = 0;
for(i = 0; i < NUM_OF_PEOPLE; i++)
{
Student * student_p = p.student[NUM_OF_PEOPLE];
}
It does not work, so can we allocate memory in the way?
And how to find the first element of struct Student in the memory?
What you have is an ancient way of having a flexible array member, which was technically also undefined behavior.
You are looking for this.
First, you need to define your struct like this (I don't know what the ints before the Students are, so let's just call it id):
typedef struct
{
int age;
int phoneNumber;
} Student;
typedef struct
{
int id;
Student student;
} StudentAndId;
typedef struct
{
int id;
StudentAndId students[];
} People;
Note the lack of size in the array inside People. Now you do this:
People *p = malloc(sizeof(People) + sizeof(StudentAndId[NUM_OF_PEOPLE]));
Then you can access students inside p as if it was an array of NUM_OF_PEOPLE elements.
Remember to compile with C99 (or C11) support. With gcc that would be -std=c99 or -std=gnu99.
This will allocate memory for storing the date but how you access it depends on how you store date. using C pointers you can store and access data using this structure and allocation but accessing the members will not be direct. it will involve pointer arithmetic. So better to use other structure if possible. If using this way of allocation then you need to do pointer arithmetic to get the next elements.
Try this:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int age;
int phoneNumber;
} Student;
typedef struct
{
int id;
int student[1];
} People;
#define NUM_OF_PEOPLE 10
int main()
{
People *p = malloc(sizeof(People) + sizeof(int) * NUM_OF_PEOPLE + sizeof(Student) * NUM_OF_PEOPLE);
int* id = (int*)(p+1);
Student* s = (Student*)(id+NUM_OF_PEOPLE);
printf("Size of People : %d\n", sizeof(People));
printf("p points to : %p\n", p);
printf("id points to : %p\n", id);
printf("s points to : %p\n", s);
}
Here's a sample output:
Size of People : 8
p points to : 0x80010460
id points to : 0x80010468
s points to : 0x80010490
You may want to add the id field to your Student data structure, e.g.:
typedef struct {
int id;
int age;
int phoneNumber;
} Student;
Then, you can define a structure having a fixed header (in this case, this can be the number of students), followed by a variable-sized array of Students:
#define ARRAY_OF_ANY_SIZE 1
typedef struct {
int count;
Student students[ARRAY_OF_ANY_SIZE];
} People;
This blog post explains this technique of having "arrays of size 1", including a discussion of the alignment problem.
I won't repeat the original blog post code here. Just consider that you can use the portable offsetof() instead of the Windows-specific FIELD_OFFSET() macro.
As a sample code, you may want to consider the following:
#include <stdio.h> /* For printf() */
#include <stddef.h> /* For offsetof() */
#include <stdlib.h> /* For dynamic memory allocation */
typedef struct {
int id;
int age;
int phoneNumber;
} Student;
#define ARRAY_OF_ANY_SIZE 1
typedef struct {
int count;
Student students[ARRAY_OF_ANY_SIZE];
} People;
int main(int argc, char* argv[]) {
People* people;
const int numberOfStudents = 3;
int i;
/* Dynamically allocate memory to store the data structure */
people = malloc(offsetof(People, students[numberOfStudents]));
/* Check memory allocation ... */
/* Fill the data structure */
people->count = numberOfStudents;
for (i = 0; i < numberOfStudents; i++) {
people->students[i].id = i;
people->students[i].age = (i+1)*10;
people->students[i].phoneNumber = 11000 + i;
}
/* Print the data structure content */
for (i = 0; i < people->count; i++) {
printf("id: %d, age=%d, phone=%d\n",
people->students[i].id,
people->students[i].age,
people->students[i].phoneNumber);
}
/* Release the memory allocated by the data structure */
free(people);
return 0;
}
Output:
id: 0, age=10, phone=11000
id: 1, age=20, phone=11001
id: 2, age=30, phone=11002
here is the struct
int main() {
typedef struct {
char firstName[25];
char lastName[30];
char street[35];
char city[20];
char state[3];
int zip;
char phone[15];
int accountId;
}Customer ;
say i fill this out with x amount of data.
what is a simple way to search the array index of this struct based on one its members, and then print that "Customers" info. Specifically I am looking to search for customers by state.
Below is an example that I believe will be of some help. Of course, the Customer definition, record printing, and data population need to be expanded. Also note that customer[] is on the stack in this example, so its members aren't zeroed and hence should be set to intended values one way or another.
#include <string.h>
#include <stdio.h>
#define NUM_RECORDS 10
int main()
{
int i;
typedef struct {
char state[3];
} Customer;
Customer customer[NUM_RECORDS];
strcpy(customer[2].state, "CA");
for (i = 0; i < NUM_RECORDS; i++)
{
// if this customer record's state member is "CA"
if (!strcmp(customer[i].state, "CA"))
printf("state %d: %s\n", i, customer[i].state);
}
// Prints "state 2: CA"
return 0;
}