How to access to 2D array of char* through structure? - c

Here is a 2D array of char*, storing for example different strings in different languages :
typedef enum
{
FRENCH,
ENGLISH,
GERMAN,
LANGUAGES_COUNT
} languages_t;
typedef enum
{
HELLO,
THANK_YOU,
WORDS_COUNT
} words_t;
char *text_tab[WORDS_COUNT][LANGUAGES_COUNT] =
{
{"bonjour", "hello", "guten tag"},
{"merci", "thank you", "danke"}
};
No trouble to access it :
int main()
{
printf("%s\n", text_tab[HELLO][ENGLISH]);
printf("%s\n", text_tab[THANK_YOU][FRENCH]);
printf("%s\n", text_tab[HELLO][GERMAN]);
return 0;
}
Now, I don't want to access text_tab directly, but through a structure :
typedef struct
{
int a;
char ***txt; // here is not working
} test_t;
test_t mystruct = {5, text_tab};
The idea is to access text_tab this way :
printf("%s\n", mystruct.txt[BONJOUR][ANGLAIS]);
printf("%s\n", mystruct.txt[MERCI][FRANCAIS]);
printf("%s\n", mystruct.txt[BONJOUR][ALLEMAND]);
How to declare the field "txt" in the structure ?
I only use static allocation and I don't want to copy the content of "text_tab" in "txt", juste use a pointer.
Thanks.

This array
char *text_tab[WORDS_COUNT][LANGUAGES_COUNT] =
{
{"bonjour", "hello", "guten tag"},
{"merci", "thank you", "danke"}
};
has the type char * [WORDS_COUNT][LANGUAGES_COUNT].
So a pointer to elements of the array has the type char * ( * )[LANGUAGES_COUNT]
Hence the structure can be declared like
typedef struct
{
size_t a;
char * ( *txt )[LANGUAGES_COUNT];
} test_t;
And in main you can declare an object of the structure type like
test_t mystruct = { sizeof( text_tab ) / sizeof( *text_tab ), text_tab };
Here is a demonstrative program.
#include <stdio.h>
#define WORDS_COUNT 2
#define LANGUAGES_COUNT 3
typedef struct
{
size_t a;
char * ( *txt )[LANGUAGES_COUNT];
} test_t;
int main(void)
{
char *text_tab[WORDS_COUNT][LANGUAGES_COUNT] =
{
{"bonjour", "hello", "guten tag"},
{"merci", "thank you", "danke"}
};
test_t mystruct = { sizeof( text_tab ) / sizeof( *text_tab ), text_tab };
for ( size_t i = 0; i < mystruct.a; i++ )
{
for ( size_t j = 0; j < sizeof( *mystruct.txt ) / sizeof( **mystruct.txt ); j++ )
{
printf( "%s ", mystruct.txt[i][j] );
}
putchar( '\n' );
}
return 0;
}
The program output is
bonjour hello guten tag
merci thank you danke

Related

Why is this C code throwing expected error

I have been having problem with this c code -
#include <stdio.h>
#include <string.h>
struct dict
{
char **inputs;
char *outputs;
};
int main(){
struct dict d;
d.inputs = {"hello","hi"};
d.outputs = "Hi!";
return 0;
}
when i run the code it shows this
main.c: In function 'main':
main.c:14:16: error: expected expression before '{' token
14 | d.inputs = {"hello","hi"};
| ^
why is this happening theres nothing wrong with this code?
The data member inputs
char **inputs;
is a scalar object. So it may be initialized using braces with only one expression.
And moreover you may not assign a braced list to an object as you are trying to do
d.inputs = {"hello","hi"};
Instead you could write for example
struct dict
{
char *inputs[2];
char *outputs;
};
int main( void ){
struct dict d = { .inputs = {"hello","hi"}, .outputs = "Hi!" };
return 0;
}
Another approach is the following
struct dict
{
char **inputs;
char *outputs;
};
int main( void ){
struct dict d;
char *s[] = {"hello","hi"};
d.inputs = s;
d.outputs = "Hi!";
return 0;
}
Or you could use a compound literal like
struct dict
{
char **inputs;
char *outputs;
};
int main( void ){
struct dict d;
d.inputs = ( char *[] ){"hello","hi"};
d.outputs = "Hi!";
return 0;
}

how to print the contents of char**?

I have a structure defined as a char** array containing strings. I dont know how to run printf on its contents.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifndef STRUCT_STRING_ARRAY
#define STRUCT_STRING_ARRAY
typedef struct s_string_array
{
int size;
char** array;
} string_array;
#endif
void my_print_words_array(string_array* param_1)
{
int len = param_1->size;
char **d = param_1->array;
for(int i = 0 ; i < len;i++){
printf("%s\n", d[i]);
}
}
int main(){
struct s_string_array *d;
d->size = 2;
char **my_arr = (char *[]){"hello", "world"};//this init is fine
d->array = my_arr;
my_print_words_array(d);
return 0 ;
}
the main function gives me segfault error. What's wrong?
There is no sense to declare a pointer to the structure
struct s_string_array *d;
moreover that is not initialized and has indeterminate value that further is a reason of undefined behavior.
What you are trying to achieve is the following
#include <stdio.h>
typedef struct s_string_array
{
int size;
char** array;
} string_array;
void my_print_words_array( const string_array *param_1 )
{
for ( int i = 0; i < param_1->size; i++ )
{
puts( param_1->array[i] );
}
}
int main( void )
{
string_array d =
{
.size = 2,
.array = (char *[]){"hello", "world"}
};
my_print_words_array( &d );
return 0 ;
}
The program output is
hello
world

C casting inside of structs from void *

I'm trying to cast a struct inside a struct but am running into issues, heres my simplified code:
#include <stdlib.h>
typedef struct {
void *test;
} abc;
typedef struct {
int a;
int b;
} def;
int main()
{
abc *mystruct = malloc(sizeof(abc) + sizeof(def));
mystruct->(def *)test->a = 3;
return 0;
}
the abc struct may have different types of structs in them, so I'd like to cast dynamically, however, this doesn't appear to work. How do I accomplish this in one statement?
Split the allocation in two parts, first:
abc *mystruct = malloc( sizeof(abc) );
But, when you try to do( if test would be properly cast )
mystruct->test->a
test member isn't pointing anywhere, and by dereferencing it you get undefined behavior.
First point it to valid memory
mystruct->test = malloc( sizeof( def ) ) ;
Then you can use it:
( ( def *)mystruct->test )->a = 3;
^ ^
Notice the parenthesis, you are casting the member void which is mystruct->test not just test.
When casting from void* the proper way is to use static_cast in C++:
abc *mystruct = static_cast<abc*>(malloc(sizeof(abc)));
mystruct->test = malloc(sizeof(def));
static_cast<def*>(mystruct->test)->a = 3;
LIVE DEMO
Now as far as it concerns C. First of, I prefer to define init and finit functions for my structs:
struct abc*
abc_init(int sz) {
struct abc *out = (abc*) malloc(sizeof(abc));
out->test = malloc(sz);
return out;
}
void
abc_finit(struct abc *in) {
if(in) {
if(in->test) free(in->test);
free(in);
}
}
Notice that allocation of struct abc is done in two steps first the memory for struct abc and then for member test.
Now the casting is done like:
((def*)(mystruct->test))->a = 3;
LIVE DEMO
More commonly you would use a union for this sort of thing:
typedef union {
struct {
int a;
int b;
} def;
/* ..other variants you might want */
} abc;
int main() {
abc *mystruct = malloc(sizeof(abc));
mystruct->def.a = 3;
/* do stuff with it */
Try the following
#include <stdlib.h>
#include <stdio.h>
typedef struct {
void *test;
} abc;
typedef struct {
int a;
int b;
} def;
int main()
{
abc *mystruct = malloc( sizeof( abc ) );
if ( mystruct )
{
mystruct->test = malloc( sizeof( def ) );
if ( mystruct->test )
{
( ( def * )mystruct->test )->a = 3;
printf( "%d\n", ( ( def * )mystruct->test )->a );
}
}
if ( mystruct ) free ( mystruct->test );
free( mystruct );
return 0;
}
The output will be
3
(Corrected) ((def *)mystruct->test)->a = 3;
type cast operator has less precedence than -> operator
Here is the reference

2D arrays and pointers

Hey All, I am a pointer newbie and in the following code, I am trying to store the values of a 2 D array in a structure and then print them. However, I get a compilation error at the line: fd->mychar[i] = newptr[i]; I get that while char * str is same as str[], char ** str isnt the same as str[][], but I cant find a solution to make the following work.
typedef struct mystruct{
char mychar [20][20];
}mystruct_t;
void printvalues ( char ** newptr){
int i;
mystruct_t * fd;
for (i=0;i<3;i++){
fd->mychar[i] = newptr[i];
printf("My value is %s and in struct %s\n", newptr[i], fd->mychar[i]);
}
}
int main (int argc, char **argv){
int i;
char * abc[5] = {"123", "456", "789"};
for (i=0;i<3;i++){
printf("My value is %s\n", abc[i]);
}
printvalues(abc);
}
Most of the issue was your use of an unallocated structure.
You used a pointer to mystruct_t but never allocated it.
The following runs for me:
#include <stdio.h>
typedef struct mystruct
{
char* mychar [20];
} mystruct_t;
void printvalues( char** newptr )
{
int i;
// note: you used an unallocated pointer in your original code
mystruct_t fd;
for ( i = 0; i < 3; i++ )
{
fd.mychar[i] = newptr[i];
printf( "My value is %s and in struct %s\n", newptr[i], fd.mychar[i] );
}
}
int main( int argc, char **argv )
{
int i;
char * abc[5] = { "123", "456", "789" };
for ( i = 0; i < 3; i++ )
{
printf( "My value is %s\n", abc[i] );
}
printvalues( abc );
}

Get the pointer of struct calling function

For the current project I cannot use C++ (unfortunately), only pure C, and Im having the following problem:
I got 3 distinctive struct that need to call the same function name, and I feel its more elegant the way it is below instead of creating 3 different function for the different type, like I feel its easier to maintain. How can I get the pointer that call the function? Basically what I'm trying to reproduce is basically similar as "this" in C++ or self (in Obj-C), is there anyway I can do that in plain C?
[ test.h ]
enum
{
TYPE_A = 0,
TYPE_B = 1,
TYPE_C = 2
};
typedef struct
{
char type;
void ( *GetType )( void );
// Some other data different than the other struct
}A;
typedef struct
{
char type;
void ( *GetType )( void );
/* Some other data different than the other struct */
}B;
typedef struct
{
char type;
void ( *GetType )( void );
// Some other data different than the other struct
} C;
A *create_a( void );
B *create_b( void );
C *create_c( void );
void GetType( void );
[ test.c ]
A *create_a( void )
{
A *a = ( A * ) calloc( 1, sizeof( A ) );
a->type = TYPE_A;
a->GetType = GetType;
return a;
}
B *create_b( void )
{
B *b = ( B * ) calloc( 1, sizeof( B ) );
b->type = TYPE_B;
b->GetType = GetType;
return b;
}
C *create_c( void )
{
C *c = ( C * ) calloc( 1, sizeof( C ) );
c->type = TYPE_C;
c->GetType = GetType;
return c;
}
void GetType( void )
{
printf("How to get the pointer that call this function to retrieve the type?");
}
[ main.c ]
int main (int argc, const char * argv[])
{
A *a = create_a();
B *b = create_b();
C *c = create_c();
a->GetType();
b->GetType();
c->GetType();
return 0;
}
The traditional way to do this kind of thing (eg in the UNIX kernel) is by using a #define for syntactic sugar:
#define GET_TYPE(X) ((X)->GetType((X)))
Of course if there are more arguments it passes those as well. The function pointers are usually collected in one static "ops" structure which is assigned on creation (instead of every individual function pointer). Each ops vector has a corresponding collection of #defines.
Pass this as a normal parameter (first, to be conventional):
void GetType(void *this);
...
GetType(a); // instead of C++-style a->GetType
It'd be better to have some "base class" (including "int type" field), in this case pointer will be "struct Base *this", not a "void *this").
Personally I always go this way. You can add prefix for a functions of some "class" (for example, Cl1_GetType). This is the way of OO-programming in C. "Real virtual functions" through function pointers could also be used, but it's not such common case.
"this" should be given as a parameter to GetType(). That's how object methods are actually implemented under the hood. Moreover, since GetType should be able to interact with all kind of struct - the structs should have a similar "base class". for example:
#include "stdio.h"
typedef enum
{
TYPE_A = 0,
TYPE_B = 1,
TYPE_C = 2
} my_class_type;
typedef struct
{
char type;
my_class_type ( *GetType )( void* );
}my_base;
my_class_type my_base_GetType( void* my_base_ptr)
{
return ((my_base*)my_base_ptr)->type;
}
typedef struct
{
my_base base;
// Some other data different than the other struct
}A;
typedef struct
{
my_base base;
/* Some other data different than the other struct */
}B;
typedef struct
{
my_base base;
// Some other data different than the other struct
}C;
A *create_a( void )
{
A *a = ( A * ) calloc( 1, sizeof( A ) );
a->base.type = TYPE_A;
a->base.GetType = my_base_GetType;
return a;
}
B *create_b( void )
{
B *b = ( B * ) calloc( 1, sizeof( B ) );
b->base.type = TYPE_B;
b->base.GetType = my_base_GetType;
return b;
}
C *create_c( void )
{
C *c = ( C * ) calloc( 1, sizeof( C ) );
c->base.type = TYPE_C;
c->base.GetType = my_base_GetType;
return c;
}
int main(int argc, char* argv[])
{
A *a = create_a();
B *b = create_b();
C *c = create_c();
printf("%d\n",a->base.GetType(a));
printf("%d\n",b->base.GetType(b));
printf("%d\n",c->base.GetType(c));
return 0;
}
This example implements inheritance and polymorphism. All structs share the same base core and if you want to override GetType() you just change the pointer in base. you can hold a pointer to my_base and dynamically resolve the type.
From what i understood of your question is: "You just want to obtain the value of the type field in the structure in GetType function". Is this right? If yes, you can do it this way:
enum
{
TYPE_A = 0,
TYPE_B = 1,
TYPE_C = 2
};
typedef struct
{
char type;
// Some other data different than the other struct
}A;
typedef struct
{
char type;
/* Some other data different than the other struct */
}B;
typedef struct
{
char type;
// Some other data different than the other struct
} C;
A *create_a( void );
B *create_b( void );
C *create_c( void );
void GetType( void * );
[test.c]
A *create_a( void )
{
A *a = ( A * ) calloc( 1, sizeof( A ) );
a->type = TYPE_A;
return a;
}
B *create_b( void )
{
B *b = ( B * ) calloc( 1, sizeof( B ) );
b->type = TYPE_B;
return b;
}
C *create_c( void )
{
C *c = ( C * ) calloc( 1, sizeof( C ) );
c->type = TYPE_C;
return c;
}
#define GetType(x) (x->type)
[main.c]
int main (int argc, const char * argv[])
{
A *a = create_a();
B *b = create_b();
C *c = create_c();
GetType(a);
GetType(b);
GetType(c);
return 0;
}
Hope this answers your question.

Resources