Why is this C code throwing expected error - c

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

Related

How can i assignment some data to a typedef struct array?

i want assignment a string to array of char in typedef struct like this
typedef struct convert{
char *upcase;
char *lowcase;
int number;
int order;
} convert;
convert sandi[27];
sandi[].upcase = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ"};
but it cannot
A typedef declaration does not declare an object and in C you may not provide default values for members of a structure.
In such a case you need to use a loop as for example
typedef struct convert{
char *upcase;
char *lowcase;
int number;
int order;
} convert;
convert sandi[27];
char *upcase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for ( size_t i = 0; i < 27; i++ )
{
sandi[i].upcase = upcase;
}

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

Parameter passing multiple values using void pointer

I want to pass multiple arguments to a function using a void pointer.
void* function(void *params)
{
//casting pointers
//doing something
}
int main()
{
int a = 0
int b = 10;
char x = 'S';
void function(???);
return 0;
}
I know that I have to cast them to a certain variable in my function but I do not know how I can pass my 3 arguments as one void pointer to my function.
I have searched for this problem know quite some time but I could not find anything that would help me.
You could do it like this:
struct my_struct
{
int a;
int b;
char x;
}
void * function(void * pv)
{
struct my_strcut * ps = pv; /* Implicitly converting the void-pointer
/* passed in to a pointer to a struct. */
/* Use ps->a, ps->b and ps->x here. */
return ...; /* NULL or any pointer value valid outside this function */
}
Use it like this
int main(void)
{
struct my_struct s = {42, -1, 'A'};
void * pv = function(&s);
}
Following up on the OP's update:
struct my_struct_foo
{
void * pv1;
void * pv2;
}
struct my_struct_bar
{
int a;
int b;
}
void * function(void * pv)
{
struct my_strcut_foo * ps_foo = pv;
struct my_struct_bar * ps_bar = ps_foo->pv1;
/* Use ps_foo->..., ps_bar->... here. */
return ...; /* NULL or any pointer value valid outside this function */
}
Use it like this
int main(void)
{
struct my_struct_bar s_bar = {42, -1};
struct my_struct_foo s_foo = {&s_bar, NULL};
void * pv = function(&s_foo);
}
The void* is used as a pointer to a "generic" type. Hence, you need to create a wrapping type, cast convert to void* to invoke the function, and cast convert back to your type in the function's body.
#include <stdio.h>
struct args { int a, b; char X; };
void function(void *params)
{
struct args *arg = params;
printf("%d\n", arg->b);
}
int main()
{
struct args prm;
prm.a = 0;
prm.b = 10;
prm.X = 'S';
function(&prm);
return 0;
}

Swift access to C Struct

I am developing a OS X Swift app for parsing cvs files. It runs successfully in Objective-C. Then I changed to Swift and for performance improvements I developed the parse/import engine in C. It is 5 times faster as in Swift or Objective-C - nice. But I have trouble to exchange the data between C and Swift - especially with Struct:
BridgingHeader:
#include "ToolBoxC.h"
ToolBoxC.h:
void loadFile(const char *fileName, const char *delimiters, const char *xRegex, int xRegexColumn, int xColumn, int yColumn, int xRow, int yRowShift, bool collectStrings);
typedef struct {
char **headerArray;
int numberHeaderRows;
char **dateArray;
int numberDateRows;
int **valueArray;
char ***stringArray;
int numberValueRows;
int numberValueColums;
} FileStruct;
typedef struct {
FileStruct fileContent[10000];
} FilesStruct;
struct FilesStruct filesContent;
ToolBoxC.c:
struct FileStruct {
char **headerArray;
int numberHeaderRows;
char **dateArray;
int numberDateRows;
int **valueArray;
char ***stringArray;
int numberValueRows;
int numberValueColums;
};
struct FilesStruct {
struct FileStruct fileContent[10000];
};
void loadFile(const char *fileName, const char *delimiters, const char *xRegex, int xRegexColumn, int xColumn, int yColumn, int xRow, int yRowShift, bool collectStrings) {
// some stuff
struct FileStruct fileContent;
fileContent.headerArray = headerArray;
fileContent.numberHeaderRows = numberHeaderRows;
fileContent.dateArray = dateArray;
fileContent.numberDateRows = numberDateRows;
fileContent.valueArray = valueArray;
fileContent.stringArray = stringArray;
fileContent.numberValueRows = numberValueRows;
fileContent.numberValueColums = numberValueColumns;
filesContent.fileContent[numberFiles] = fileContent;
return;
}
All the parsed data are stored in struct FilesStruct filesContent. The parsing is started by calling the function loadFile() with parameters from Swift. That works fine. Also the parsing is OK. But how can I access to the data in struct FilesStruct filesContent from Swift?
Thanks, Matthias.
Try this:
ToolBoxC.h
#include <stdbool.h>
struct FileStruct {
char **headerArray;
int numberHeaderRows;
char **dateArray;
int numberDateRows;
int **valueArray;
char ***stringArray;
int numberValueRows;
int numberValueColums;
};
extern struct FileStruct **loadedFiles;
void loadFile(const char *fileName, const char *delimiters, const char *xRegex, int xRegexColumn, int xColumn, int yColumn, int xRow, int yRowShift, bool collectStrings);
ToolBoxC.c
#include <stdlib.h>
#include "ToolBoxC.h"
#define MaxFiles 10000
struct FileStruct **loadedFiles;
void loadFile(const char *fileName, const char *delimiters, const char *xRegex, int xRegexColumn, int xColumn, int yColumn, int xRow, int yRowShift, bool collectStrings) {
static int nextIndex = 0;
if (loadedFiles == 0)
loadedFiles = malloc(MaxFiles * sizeof(*loadedFiles));
struct FileStruct *file = malloc(sizeof(struct FileStruct));
file->numberDateRows = xRow;
loadedFiles[nextIndex++] = file;
}
Swift Test Method
func loadFilesTest() -> Void {
for var i:Int32 = 0; i < 10; ++i {
loadFile("", "", "", 0, 0, 0, i, 0, true)
}
for var j = 0; j < 10; ++j {
let pointer = UnsafePointer<FileStruct>(loadedFiles[j])
print("Number of date rows = \(pointer.memory.numberDateRows)")
}
}

qsort of struct array not working

I am trying to sort a struct run array called results by a char, but when I print the array, nothing is sorted. Have a look at this:
struct run {
char name[20], weekday[4], month[10];
(And some more...)
};
typedef struct run run;
int name_compare(const void *a, const void *b)
{
run *run1 = *(run **)a;
run *run2 = *(run **)b;
return strcmp(run1->name, run2->name);
}
int count_number_of_different_persons(run results[])
{
int i = 0;
qsort(results, sizeof(results) / sizeof(run), sizeof(run), name_compare);
for(i = 0; i <= 999; i++)
{
printf("%s\n", results[i].name);
}
// not done with this function yet, just return 0
return 0;
}
The output from the above is just a list of names in the order they were originally placed
int count_number_of_different_persons(run results[])
This doesn't really let you use sizeof on the array, because array is decayed to pointer.
This
run *run1 = *(run **)a;
also looks weird, shouldn't it be
run *run1 = (run*)a;
?
One problem is in name_compare. Try this instead:
int name_compare(const void *a, const void *b)
{
run *run1 = (run *)a;
run *run2 = (run *)b;
return strcmp(run1->name, run2->name);
}
Check the following code:
As #michel mentioned, sizeof(array) provides size of the pointer, not the size of the array itself, as while passing array it is treated as a pointer. Hence either send the number of elements to the function count_number_of_different_persons or define a MACRO of number of elements. Hope this helps. :).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define NOE 3
struct run
{
char name[20];
};
typedef struct run run;
int name_compare (const void *a, const void *b )
{
return strcmp (((run *)a)->name, ((run *)b)->name);
}
int count_number_of_different_persons(run results[], int noOfElements)
{
int i=0;
qsort(results, noOfElements, sizeof (run), name_compare);
for (i=0; i<noOfElements; i++)
printf ("%s\n",results[i].name);
}
int main ( int argc, char * argv[])
{
run a, b, c;
run arg[NOE];
strcpy (a.name, "love");
strcpy (b.name, "you");
strcpy (c.name, "i");
arg[0] = a;
arg[1] = b;
arg[2] = c;
count_number_of_different_persons(arg, sizeof(arg)/sizeof(run));
};

Resources