fprintf() to a csv file in C by using pointer - c

I have a structure defined like this
typedef struct{
int id;
char* name;
float percentage;
}student_t;
And there is a function that is to print struct's member in this format
"id, name, percentage\n"
But the function takes in void* val_ref //struct ptr, void* fp
How do I make it work? The function looks like this (paramters are given cannot be modified)
void printStudentInfo(void* val_ref, void* fp)
{
if (val_ref != NULL)
{
fprintf(fp, "%d,%s,%.2f", val_ref->id, val_ref->name, val_ref->percentage);
}
}
But I can't compile, it says warning: deferencing void* pointer
error: request for memeber "id" in something not a struct or union
error: request for memeber "name" in something not a struct or union
error: request for memeber "percentage" in something not a struct or union
Do I have to do type cast for parameter val_ref?

fprintf(fp, "%d,%s,%.2f", val_ref->id, val_ref->name, val_ref->percentage); Over here, you need to cast val_ref to the type of pointer it actually is: (student_t *)val_ref and then fetch a member of the struct for e.g. ((student_t*)val_ref)->id.
When you have a void*, your program does not know the actual data type you are pointing to. Hence, it is illegal to try to fetch a member. Upon using a cast, you are explicitly saying that val_ref points to a student_t and you know what you are doing when you ask for a specific member.
However, there is no need to cast fp because the function fprintf has the first argument as FILE * in it's signature:
int fprintf(FILE *stream, const char *format, ...);
So, even if you pass a void * as the first parameter, the local variable stream is defined as a FILE * and that's what the function works with.

Related

Getting the value inside a pointer pointed by another pointer?

I have a queue that stores thread structures
struct x
{
int n;
char *c;
void *f;
};
The function below returns a structure defined as the following:
struct s {
void *data;
};
When I call *new = allocate(&x_ptr), how can I access the members of x?
I tried the following but it does not work:
printf("%d\n", new ->data->n)
I get this error: request for member ā€˜nā€™ in something not a structure or union
data has type of void *, you need to cast it to the correct pointer type (assuming it is referencing a valid object of that type).
printf("%d\n", node->data->threadid);
---->
printf("%d\n", ((threaddesc *)(node->data))->threadid);

error: expression must have struct or union type in c when passing struct as param in function

I have such a struct
struct Request
{
char command[COMMAND_LENGHT];
char firstSetName[SET_NAME_LENGTH];
char secondSetName[SET_NAME_LENGTH];
char resultSetName[SET_NAME_LENGTH];
int input[sizeof(int) * 4];
};
and I have such a method
int parseToReadRequest(char * command, struct Request ** request)
{
printf("Command is : %s\n", command);
*request.firstSetName = "firs";
return 0;
}
As far as I understood when you need to pass a struct as a param you need to mark it with **
but anyway when I try to assign a struct value firstSetName I get an error
Expression must have struct or union type
What am I doing wrong?
EDIT
I get such error
In this expression:
*request.firstSetName = "firs";
The member access operator . has the highest precedence, so it assumes that request is a struct or union type. However it is not. It is a pointer-to-pointer-to struct.
If your intent is to modify an instance of a struct, you don't need a double pointer. Just a single will do:
int parseToReadRequest(char * command, struct Request *request)
Then, you would need to either put parenthesis around *request to ensure the pointer is first dereferenced before using .:
(*request).firstSetName = "firs";
Or you can use the pointer-to-member operator -> which is cleaner:
request->firstSetName = "firs";
However there is another issue here. You're attempting to assign a value to an array. An array can't be assigned to directly. What you want instead is to use the strcpy function which is used to copy strings:
strcpy(request->firstSetName, "firs");
You have to pass the structure by reference, ie. pass the pointer to it. You need to pass a double pointer only if you need to modify the pointer itself (for example dynamically allocate a structure inside the function).
The function should be: int parseToReadRequest(char * command, struct Request * request)
And inside the function you should access the structure fields like this: request->firstSetName

Why does my code give `Structure-return value does not match function type` compile error?

I have code as:
typedef struct t
{
uint8 a[100];
}t;
t tt; //object of the struct
f(&tt); //some file calling the func
//function body in some file
uint8 *f(const struct t *ptr)
{
return ptr->a;
}
When I try to build I get the error:
Return value type does not match the function type.
Am I missing something?
You need to use the name of the type, there is no struct t type defined anywhere in your code, so
uint8 *f(t *const tt);
should be the function signature, of course I suppose you are using meaninful names in your real code.
Also, note that I didn't make the pointee const because if you return a non-const pointer to a const pointer to the structure then undefined behavior might happen, the alternative being of course
const uint8 *f(const t *const tt);
The second const, just prevents accidentaly reassigning tt.

access members of a structure from void pointer inside a structure

I want to access members of a structure from void pointer inside a structure, I have tried the following code but it is giving error as "expected identifier before ā€˜(ā€™ token". what should I change in printf statement? Thanks in advance.
#include "stdio.h"
struct
{
int date;
char *name;
}test;
struct
{
void *check;
}massage;
main()
{
test.date=21;
test.name="Nilesh";
massage.check =&test;
printf("date - %d , name - %s\n",massage.((struct test *)check)->date,massage.((struct test *)check)->name);
}
struct // anonymous struct type
{
int date;
char *name;
} test;
The above statement defines an anonymous struct type and creates a variable test of this struct type which has no name. Similarly, the below statement defines an anonymous struct type and creates a variable massage of this type -
struct // anonymous struct type
{
void *check;
} massage;
The typecast operator must have a type in the parentheses (type), not a variable name. Therefore, you must give the first struct a name (tag) so as to use the typecast operator. Also, the result of a typecast operator is an r-value and therefore it cannot be used with member selection .(dot) operator (it should be the name of the member). Therefore, the typecast operator should be applied after the value is fetched from the structure. Therefore, the following expression is wrong -
massage.((struct foo *)check)->date
// |____________________|
// |
// this should be the member name but it
// evaluates to a r-value - the result of
// the typecast operator assuming struct tag
// is foo
// it should instead be
((struct foo *)massage.check)->date
// dot operator has higher precedence than typecast
// so the struct member check is fetched first and
// it is typecast to type (struct foo *)
I suggest the following changes -
// standard headers should be
// enclosed in angle < > brackets
#include <stdio.h>
// give the structure a name so it can be
// used in typecasting
struct foo {
int date;
char *name;
} test;
// anonymous struct type
struct {
void *check;
} massage;
// return type of main should be int and
// parameter list should contain void
int main(void) {
test.date = 21;
test.name = "Nilesh";
massage.check = &test;
// fetch the struct member check and then
// apply typecast operator
printf("date - %d , name - %s\n", ((struct foo *)massage.check)->date,
((struct foo *)massage.check)->name);
return 0;
}
In your expression:
massage.((struct test *)check)->date
// ^^^ is variable not a data-type
there are two mistakes:
You can't type case into a variable, in your code test is a variable not a type so (struct test *) is wrong expression. You should name the user-defined type (as I have suggested below).
You are applying typecasting without accessing massage's pointer member. So in expression (struct test *)check, actually "check" is unknown variable. compiler will error you "check" is undeclared variable (thought test is not a datatype but the order of applying type casting is conceptually wrong).
I am suggesting a couple of correction try with it:
Name the stuct e.g. newtype
struct newtype // notice I given name to user defined datatype
{
int date;
char *name;
}test;
Then correct second and third argument in printf function as below
((struct newtype *)massage.check)->date
// ^^^^^^^^^^^^^^ notice
Similarly third argument in printf. First access member then type cast to correct type.
For full code refer Ajay's answer.
The struct definition is not want you want -- it defines an object test of an unnamed struct type. Try
struct testType
{
int date;
char *name;
} test;
and then cast to (testType *).

Casting a void pointer to a struct

I started feeling comfortable with C and then I ran into type casting. If I have the following defined in an *.h file
struct data {
int value;
char *label;
};
and this in another *.h file
# define TYPE void*
How do I cast the void pointer to the struct so that I can use a variable "TYPE val" that's passed into functions? For example, if I want to utilize the value that TYPE val points to, how do I cast it so that I can pass that value to another functions?
(struct data*)pointer
will cast a pointer to void to a pointer to struct data.
Typecasting void pointer to a struct can be done in following
void *vptr;
typedef struct data
{
/* members */
} tdata;
for this we can typecast to struct
lets say u want to send this vptr as structure variable to some function
then
void function (tdata *);
main ()
{
/* here is your function which needs structure pointer
type casting void pointer to struct */
function((tdata *) vptr);
}
Note: we can typecast void pointer to any type, thats the main purpose of void pointers.

Resources