newbie
newbie

Reputation: 1217

How can I test the -> C operator using a struct that allows me to access a struct's field?

I'm trying to test the -> operator, but I can't seem to do that, because when I execute the following program and feed the input with a stream, the program stops working.

Note1: I get a warning before compiling, it says that:

format '%s' expects argument of type 'char *', but argument 2 has type 'int' [-Wformat=]

Note2: if I omit the line printf("%s\n", *(&home1)->name ), it works just fine, and actually prints whatever I wrote.

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

typedef struct home_type {
    char name[30] ;
}home;

int main (void) {
    home home1 ;
    char name[30] ;
    scanf ("%[^\n]%*c", name);
    strcpy( home1.name, name) ;
    printf("%s\n", home1.name ) ;
    printf("%s\n", *(&home1)->name ) ;
    return 0 ;
}

Upvotes: 2

Views: 140

Answers (4)

P.P
P.P

Reputation: 121407

You just have to drop the * (i.e. not dereference):

printf("%s\n", (&home1)->name );

The member name is an array which gets converted into a pointer (char*) when passing to printf(). However, when you dereference it, it's just a single char that you pass. Obviously, it doesn't match with what printf() expects for the format %s.

See: What is array decaying?

Upvotes: 5

Petr Skocik
Petr Skocik

Reputation: 60107

(&home1)->name is the member array. *(&home1)->name is a dereference on the member array which because of array decay is equivalent to (&home1)->name[0]. This has type char. Passing a char through the ... of a variadic function such as printf promotes it to int (... causes default argument promotions to apply).

Upvotes: 5

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726849

Operators -> and . are interchangeable:

  • obj.field is the same as (&obj)->field
  • ptr->field is the same as (*ptr).field

Note that you have added an asterisk to the result of (&home1)->name, which produces a char. Since printf is a variable-argument function, char is promoted to int during the call, explaining the warning.

When you pass an int for a parameter expecting a pointer, undefined behavior happens; in your case, the program crashes. Removing the dereference operator * will fix this problem.

Upvotes: 5

Remove * and it works. Your code *(&home1)->name is analogous to *(home1.name) e.g. instead of passing the pointer to the first character, it passes the value of the first char in name; due to default argument promotions, that value is converted into an int.

Thus:

printf("%s\n", (&home1)->name );

should work; however you don't need -> here; -> is now just a shortcut for using a pointer-to-structs more conveniently; i.e. (*ptr).name into a more palatable ptr->name; as home is already a struct and not just a pointer to struct, you should use the . instead.

Upvotes: 6

Related Questions