허민선
허민선

Reputation: 57

Nested structures and pointers in C

The compiler gives two complaints:

error: incompatible type for argument 1 of 'printout'

warning: expected struct users * but argument is of type 'users'

How do I fix these? And please check if the function printout is OK.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct{
   char username[25];
   char firstname[25];
   char lastname[25];
   int age;
}users;

typedef struct{
   users data;
   int id;
}publicusers;

users createuser(char *uname, char *fname, char *lname, int fage);
void printout(users *data);

int main(){
    printout(createuser("kway","minseon","huh", 25));
    return 0;
}

users createuser(char *uname, char *fname, char *lname, int fage){
    publicusers user1;
    strcpy(user1.data.username, uname);
    strcpy(user1.data.firstname, fname);
    strcpy(user1.data.lastname, lname);
    user1.data.age = fage;
    return user1.data;
}

void printout(users *data){
    printf("username:  %s\n",data->username);
    printf("firstname: %s\n",data->firstname);
    printf("lastname:  %s\n",data->lastname);
    printf("age:       %d\n",data->age);
}

Upvotes: 1

Views: 75

Answers (2)

nglee
nglee

Reputation: 1933

Your warning and error messages are generated from the following line:

printout(createuser("kway","minseon","huh", 25));

Function printout expects user * type value as its argument but function createuser returns user type value.

To fix this, you should pass user * type value as parameter using & operator. Change above one line code into two lines of code:

users u = createuser("kway","minseon","huh", 25);
printout(&u);

There's another way to fix this. You can change the parameter type of function printout from user * to user.

Your code should be:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct{
   char username[25];
   char firstname[25];
   char lastname[25];
   int age;
}users;

typedef struct{
   users data;
   int id;
}publicusers;

users createuser(char *uname, char *fname, char *lname, int fage);
void printout(users data);                     // parameter type changed

int main(){
    printout(createuser("kway","minseon","huh", 25));
    return 0;
}

users createuser(char *uname, char *fname, char *lname, int fage){
    publicusers user1;
    strcpy(user1.data.username, uname);
    strcpy(user1.data.firstname, fname);
    strcpy(user1.data.lastname, lname);
    user1.data.age = fage;
    return user1.data;
}

void printout(users data){                     // parameter type changed
    printf("username:  %s\n",data.username);   // -> operator changed to . operator
    printf("firstname: %s\n",data.firstname);  // -> operator changed to . operator
    printf("lastname:  %s\n",data.lastname);   // -> operator changed to . operator
    printf("age:       %d\n",data.age);        // -> operator changed to . operator
}

Upvotes: 1

RoiHatam
RoiHatam

Reputation: 896

Your createuser function returns the users type and your function printout accepts users* as its argument which is a pointer to users.

Because you are declaring your struct publicusers user1 inside your createuser function you cannot send its address as a return value. The fast solution is to change the function definition from:

void printout(users *data);
void printout(users *data){
   printf("username:  %s\n",data->username);
   printf("firstname: %s\n",data->firstname);
   printf("lastname:  %s\n",data->lastname);
   printf("age:       %d\n",data->age);
}

to

void printout(users data);
void printout(users data){
   printf("username:  %s\n",data.username);
   printf("firstname: %s\n",data.firstname);
   printf("lastname:  %s\n",data.lastname);
   printf("age:       %d\n",data.age);
}

This will create a copy of the struct users. If you want to avoid creating a copy you should consider creating publicusers user1 in your main and send it as an extra argument to the users createuser function.

Upvotes: 2

Related Questions