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

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;

Related

general array printer function in c

I've those two structs :
typedef struct
{
char* name;
int flightCount;
Flight** flightArr;
LIST dateList;
int flightsSorted;
}Airline;
typedef struct
{
Airport* airportsArr;
int airportsCount;
}AirportManager;
and I need to write a general printer for both arrays (one is struct array and the other is pointer array).
I know that general printer should look like that:
void generalArrayFunction(const void* pArr, const int size, int sizeOfElement, void(*printer)(const void*))
{
for(int i=0;i<size;i++)
printer((char*)pArr + i * sizeOfElement);
}
and it's work great with the regular array which I print with the following line:
generalArrayFunction(manager.airportsArr,manager.airportsCount,sizeof(manager.airportsArr[0]),printAirport);
but with the pointer array I can't use the same logic and I dont know what should I do.the following line prints one struct but the second one messed up.
generalArrayFunction(*pComp->flightArr, pComp->flightCount, sizeof(pComp->flightArr[0]), printFlight);
any suggestions ?
If i got your intention right, In this code:
generalArrayFunction(*pComp->flightArr, pComp->flightCount, sizeof(pComp->flightArr[0]), printFlight);
sizeOfElement will be the size of a pointer because it's an array of pointers, you need to make another dereference to reach the struct and get the size, that's why the first struct is printing ok and the subsequent are not.
Try this:
generalArrayFunction(*pComp->flightArr, pComp->flightCount, sizeof((*pComp->flightArr)[0]), printFlight)

ANSI C: Declare a pointer of type "array of string"

I have a structure like this
struct {
int id;
char str00[10];
char str01[10];
char str03[10];
char str04[10];
...
} myStructure;
All strXX have the same size. I would like to access them via an array (strArray), like this :
strcpy(strArray[i], strValue);
How to declare strArray ?
I used this:
char (*strArray)[][10] = (void *)&myStructure.str00;
It's working, but I have to code the strcpy like this
strcpy((*strArray)[i], strValue);
... and I don't like this :-)
Is there another way to declare strArray ?
Thanks for your ideas and help.
You almost had it, the correct pointer type is simply char (*ptr)[10].
Naively, you could use this pointer type to iterate over the struct members, but doing so would invoke undefined behavior. Because strictly speaking, a pointer can only point at single item or an array, and if we use pointer arithmetic to go beyond that single item/array, we invoke undefined behavior.
I'll include an example still, for the sake of demonstrating array pointer arithmetic:
// BAD CODE, it relies on undefined behavior!
#include <stdio.h>
#include <string.h>
typedef struct {
int id;
char str00[10];
char str01[10];
char str02[10];
char str03[10];
} myStructure;
int main(void)
{
myStructure ms = { 0 };
char (*ptr)[10] = &ms.str00;
for(size_t i=0; i<4; i++)
{
strcpy(ptr[i], "hello ");
strcat(ptr[i], (char[]){i+'0', '\0'});
}
puts(ms.str00);
puts(ms.str01);
puts(ms.str02);
puts(ms.str03);
return 0;
}
The proper solution is to instead use a union, so that you can access the members either individually, or as an array:
typedef union {
struct // anonymous struct, requires a standard C compiler
{
char str00[10];
char str01[10];
char str02[10];
char str03[10];
};
char array[4][10];
} str_t;
typedef struct {
int id;
str_t str;
} myStructure;
strcpy(ms.str.array[i], ...); // access as array
puts(ms.str.str00); // access as individual item
The cleanest way to define strArray as requested would be to make it an array of pointers to the (first elements of the) arrays in myStructure:
char *strArray[] = { myStructure.str00, myStructure.str01, myStructure.str03, myStructure.Str04, … };
With this definition, strArray[i] is initialized to the corresponding member of the structure, such as myStructure.str01. Note that myStructure.str01 will be automatically converted to a pointer to its first element, so strArray[i] is a pointer to the first char in one of the arrays.
Then strArray[i][j] is char j of array i.
(Incidentally, you skip str02 in your sample code. I do not know why but have retained that in the code above.)
An alternative method would be to use a union, which can be done in various ways, one of which is:
struct
{
int id;
union
{
struct
{
char str00[10];
char str01[10];
char str03[10];
char str04[10];
...
};
char strArray[number of arrays][10];
};
} myStructure;
That is generally a poor design, as it is needlessly confusing. (While this has a technical possibility of failure due to padding between the individually defined arrays, assertions can be used to ensure this does not occur, or rather to detect when it does.)
Most often, we would simply define the strings as an array of arrays:
struct
{
int id;
char str[number of arrays][10];
} my Structure;
Then the members would always be referred to by index, such as myStructure.str[1], and not by individual names, such as myStructure.str01.

Subscripted value is neither array nor pointer nor vector at array index

(Homework question)
I'm just learning C, and I'm making a program that reads data from a file, creates routers of that data, and puts pointers to the routers in an array of size 255, but I keep getting the title error on the line where I'm trying to add them to the array
#define ARRAY_SIZE 255
struct router routers[ARRAY_SIZE] = {0};
int main(int argc, char *argv[]){
unsigned char id;
char name[32];
struct router *new_router;
if(argc == 2){
//reads file with fread
//setting id and name which prints out as expected
new_router = make_router(id, name); //initialising method that returns a router pointer
routers[new_router->id] = new_router;
//error occurs here, at [new_router->id]. Have also tried just using id
}
}
I've searched a lot of threads with the same error message, but they're all either someone who didn't declare an array, or were suggested to try it with unsigned char as index number, which is what I'm already using. Would love some insight into this.
struct router{
unsigned char id;
char name[32];
}
struct router* make_router(unsigned char id, char* name){
struct router *r = malloc(sizeof(struct router));
r->id = id;
r->name = name;
return r;
}
Assuming make_router allocates a struct dynamically, then
routers[new_router->id] = *new_router; // note *
solves the compiler error.
However, you cannot copy structs like this if they have pointer members. You say that "Router is just a basic struct with an unsigned char for id, and a char* for name" so this is the case. But with an assignment like this, you won't get a hard copy of the pointed-at data.
Pointers are not data. They do not contain data. They point at data allocated elsewhere.
So probably what you are actually looking for is an array of pointers, as suggested in another answer. If so, you have to re-write this program.
This:
struct router routers[ARRAY_SIZE] = {0};
means routers is an array of ARRAY_SIZE structures. Not pointers to structures, which is what this:
routers[new_router->id] = new_router;
is trying to assign into one of the elements.
If make_router() is dynamically allocating the memory, the fix is probably to change the array declaration into an array of pointers:
struct router * routers[ARRAY_SIZE];
^
|
way
important
EDIT: Of course, I assumed that there was an actual declaration of struct router somewhere that you just omitted. Might be a good idea to include it, just for completeness' sake.

Initializing size of struct array after declaration in C?

I've done some searching around, but nothing I've found has answered my question specifically regarding structs:
In my program I have two structures: one contains data, the other contains an array of the first structure (used to make returning struct arrays easier).
I do not know the size of the aforementioned structure array until running a few lines of code. From what I've found there isn't a way to define the size of an array (or any type) after it has already been declared, although I would like to know if this holds true for structs.
If not, is there way to define the size of a previously declared array within a struct without using malloc? Using malloc with struct arrays seems a bit complicated and I haven't been able to wrap my head around it.
typedef struct
{
char **data;
} struct1;
typedef struct
{
struct1 data[];
} struct2;
int main(int argc, char **argv)
{
//Pretend there is code here that finds the size I need
size = 5;
struct2 Info;
Info.data = new struct1[size]; //Clearly this won't work, but does C offer anything comparable?
return 0;
}

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.

Resources