Initialization of char array in a struct - c

I was writing a structure from a book, and then see how it does initialization.
I don't get it, how he does that.
struct node
{
char target[50];
char stack[50];
char *s,*t;
int top;
}
Initialization function:
void init
{
p->top = -1;
strcpy(p->target,"");
strcpy(p->stack,"");
p-t = p->target;
p->s="";
}
So I want know how he is using strcpy to initialize an array or char.

He is not doing it. The statement strcpy(p->target,""); does not initialize the 50 positions of the array. It just puts a 0 in the first position. (See this reference.)

Have a look at the example in this: http://www.cplusplus.com/reference/clibrary/cstring/strcpy/

Related

access array using pointer to array stored in a struct C

I have a struct defined as following:
typedef char *element_t;
typedef
struct {
element_t *array; /* start of the array */
int capacity; /* number of elements the array */
int length; /* used portion of array, 0..capacity */
} list;
I am trying to access the array that *array points to and assign it a char value and print it.
I'm a bit rusty with C but this is how i'm trying to do it:
list.array[0] = "a";
printf("%s\n", list.array[0]);
This makes my program crash. Any fixes?
EDIT: I should also mention that I have done the following initialisations too:
element_t* array[LMAX];
list.array= *differentArray;
Seems to work for me:
typedef char *element_t;
typedef
struct {
element_t *array; /* start of the array */
int capacity; /* number of elements the array */
int length; /* used portion of array, 0..capacity */
} list;
int main(int argc, char **argv)
{
element_t array[2] = {"foo", "bar"};
list list;
list.array = array;
list.capacity = sizeof(array)/sizeof(array[0]);
list.length = 1;
printf("%s\n", list.array[0]);
return 0;
}
You are most likely forgetting to assign list.array to point to a valid array.
typedef char *element_t; Don't hide pointers behind typedefs, this is bad practice as it makes the code unreadable. element_t *array will be the same as char** array. Is this actually what you want?
list.array[0] = "a"; suggests that you intended "array" to be an array of pointers? Where do you allocate the actual array? Where do you initialize the struct? list.array[0] is pointing into la-la-land rather than at allocated memory, as far as I can tell from the posted code.
Also, the array of pointers need to be of type const char*, since you are pointing at string literals.
Change your initialization to:
element_t differentArray[LMAX];
list.array = &differentArray[0];
The rest of your code should work as is after this change. You don't need any further allocations as long as you only keep putting literals like "a" into it.

How to correctly define an array of structures?

i have the following structure:
typedef struct Course {
int course_id;
char* course_name;
int prior_course_id;
StudentTree* students;
} Course;
and the following function i need to implement:
void createReport(FILE* courses[], int numOfCourses, FILE* studentFile, char* reportFileName
as you can see i get an array of FILE*, each cell contains different file pointer.
my intention is to create an array that each cell is Course* type, and initialize each cell with a Course struct containing the data read from the courses files.
what is the correct way to declare it inside the function?
do i need to dynamically allocate memory for it, or it can be done in compilation?
i've tried
Course* course_array[numOfCourses] = {NULL};
Course* course_array[numOfCourses] = NULL;
but it won't compile.
thanks for your help
You declare an array of structs the same way you declare an array of ints or FILE *s:
Type variableName[numberOfElements];
Before C99 (and barring compiler specific extensions), creating an array with a variable number of elements on the stack wasn't supported. So make sure that you are targeting the correct standard. In your case, assuming C99 support, the following should work:
Course *course_array[numOfCourses];
Because you intend to initialize each of the elements in the array, there is no need to zero them out.
You would then access the elements like this:
course_array[0] = malloc(sizeof(Course))
course_array[0]->course_id = 2;
/* etc. */
Now if you can't assume C99 support, things get a bit more tricky but not much:
Course *course_array = malloc(sizeof(Course *) * numOfCourses);
After that you can access course_array with the same array notation:
course_array[0] = malloc(sizeof(Course))
course_array[0]->course_id = 42;
/* etc. */
Once you're doing with the array, you'll need to make sure that you free any of the memory that you allocated:
for (i = 0; i < numOfCourses; i++) {
free(course_array[i]);
}
/* If you malloc'd course_array, then you need this too */
free(course_array);
Course* course_array[numOfCourses] = {NULL};
This is good, but it creates array of Course *. So you need to allocate memory for each pointer in course_array before accessing it.
Something like
course_array[0] = malloc(sizeof(Course));
course_array[0]->course_id = someid;
When you define the array in the first place, you shouldn't need to allocate memory. You're defining the array on the stack, and the elements of the array are just pointers.
I think what you should do is first define the array, and then initialize each element with a malloc call. For example:
Course* course_array[numOfCourses];
for(int i = 0; i < numOfCourses, i++) {
course_array[i] = (Course*)malloc(sizeof(Course));
My favorite way:
typedef struct {
int a;
char b;
float c;
}DATA;
//then use typdef'ed DATA to create array (and a pointer to same)
DATA data[10], *pData;
//then, in function, you can initialize the pointer to first element of array this way:
int main(void)
{
pData = &data[0];
return 0;
}
Your example code would look like this:
typedef struct {
int course_id;
char* course_name;
int prior_course_id;
StudentTree* students;
} COURSE;
//then in function:
COURSE course[numOfCourses]

How to convert pointer array to char array?

I have this:
typedef struct nodebase{
char name[254];
char sex;
int clientnum;
int cellphone;
struct nodebase *next;
struct nodebase *encoding;
} clientdata;
I have added clientdata *curr[]; in seperate function. The reason why I made *curr into *curr[] instead is that this client data will be stored in a .txt file. So I came up with singly linked-list to read all the data and when the program fscanf every 5th variable, I will add 1 to clientcounter.
So, the *curr[] will be *curr[clientcounter].
Now, I need to convert this pointer array into char array named temp[clientcounter] because char array is needed to evaluate something else later in the code.
I came up with this code below:(Using Tiny C on Windows)
void loaded_data_transfer(clientdata *curr,clientdata temp[],int clientcounter)
{
clientdata temp[] = {0};
temp[clientcounter].name = curr[clientcounter]->name;
temp[clientcounter].sex = curr[clientcounter]->sex;
temp[clientcounter].clientnum = curr[clientcounter]->clientnum;
temp[clientcounter].cellphone = curr[clientcounter]->cellphone;
}
The problem is, Tiny C is giving me an error: lvalue expected at temp[clientcounter.name = ... part. Can anyone tell me what did I do wrong?
And if anyone knows a better way to keep track of the curr of clientdata by using counter and by using singly linked-list, please let me know.
You cannot assign an array to another. You should use strcpy or strncpy
strcpy(temp[clientcounter].name, curr[clientcounter]->name);
Maybe you meant to copy the entire struct:
void loaded_data_transfer(clientdata * curr, clientdata temp[], int clientcounter)
{
temp[clientcounter] = *curr; // Copy entire struct
}
It should work, because your struct doesn't any pointer members.
I am assuming you use it like this
clientdata * curr[CURR_SIZE];
clientdata temp[TEMP_SIZE];
/* init curr elements here */
loaded_data_transfer(*curr[clientcounter], temp, clientcounter);
Also, your declaration should be:
void loaded_data_transfer(clientdata *curr[],...

a way to copy a 2dimensional array into a struct array

I have this array filled up with characters in my maze.c file:
char normalMazeArray[6][12]; dynamically filled as mazeArray[row][column]
Now I want to pass what the array to the mazeArray that is located in my struct (maze.h)
my struct is called:
typedef struct {
char mazeArray;
} maze_t;
I have tried copying it as follows:
maze_t* maze;
char normalMazeArray[6][12]; // filled with info
typedef struct {
char mazeArray;
} maze_t;
maze->mazeArray = normalMazeArray;
however it is not working,
anyone who could help me?
The thing what you're trying to do is not exactly possible. There are two slightly different solutions you can use, though.
normalMazeArray is of type char [6][12] - it's an array. You can either copy its contents to the same type of array using memcpy():
typedef struct {
char mazeArray[6][12];
} maze_t;
memcpy(maze->mazeArray, normalMazeArray, sizeof(normalMazeArray));
or if your normalMazeArray persists throughout the lifetime of the program, you can assign a pointer to it in the structure:
typedef struct {
char (*mazeArray)[12];
} maze_t;
maze->mazeArray = normalMazeArray;
Wait, how??
First of all, maze is a pointer, so you can't have maze.mazeArray. Second of all, maze->mazeArray is of type char, while mazeArray is of type char**. No can do.
You should write a function which allocates char** array, and then strdups strings from mazeArray. Or, if you want ownership transfer, and not just copy, you could go like this:
typedef struct {
char** mazeArray;
} maze_t;
maze_t maze;
maze.mazeArray = mazeArray;

How to define a data type for holding string and numbers in C

C structure question
I have a list of words and their corresponding frequencies:
word 10
the 50
and 35
overflow 90
How should I hold this data in a structure? Should I use a two dimensional array? I should also note I have to sort them by their frequency, so I'm thinking an array of some sort then apply qsort, but I need to preserve the integers so if I use a char array I have to do back and forth casting
Possibly a struct:
struct WordInfo {
char *word;
int frequency;
};
Then you can make an array of these structs:
struct WordInfo words[128]; // whatever
And finally write a comparator function like this:
int word_compare(const void *p1, const void *p2)
{
struct WordInfo *s1 = p1;
struct WordInfo *s2 = p2;
return s1->frequency - s2->frequency;
}
If you know the maximum number of characters for the string which you are going to handle means use array and int data type inside a structure.
typded struct _data
{
char word[MAX_CHARS];
int freq;
}DATA;
...
DATA *d = malloc(sizeof(DATA) * n);
If you dont know the max characters of word go for pointer charater char *word;. In this case memory allocation will happen for each entry which will affect the performance and it will cause more fragmentation.
Its better to allocate a chunk of memory once rather than allocating small memory for n times.
You can also have an array of std::pair
Then you can run whatever sorting algorithm you want to sort the array based on the second element.
For example you will have:
std::pair myArray[size];
Define a structure type, something like
struct wordAndFrequency
{
char *word;
int count;
};
then take an array of struct wordAndFrequency and qsort that.
typedef struct Dict {
char *word;
int frequency;
} Dictionary;
Now create array of this structure object and use it as hashmap. When you come across a word, see if this word is there, increment the counter else add this word with count as 1.
Dictionary *dictionary=(Dictionary*)malloc(sizeof(Dictionary)*SIZE);

Resources