0

This is my function in my main

int get_name(void){
  char name;
  printf("Please enter the student name: ");
  scanf("%s", &name);

  return name;
}

I initialize my struct which is

typedef struct{
  char name[MAXSTRING];
  int id;
}student;

by doing

    name = get_name();

    number= get_id();

    student s1 = {.name=name , .id=number};

    printf("id is %d\n",s1.id);

    printf("name is %s\n", s1.name);

But what i get as a return is the first character of the string i enter. MAXSTRING is defined in my student.h as

#define MAXSTRING 20

I am pretty sure i have to modify my name variable in some way but i tried a lot of things and nothng worked. Also is it better to use fgets in this scenario?

4 Answers4

2

you have to provide a char array, not a pointer on a char. Then you cannot return the local array to the outer scope, so I'd suggest that you allocate the buffer:

char *get_name(void){
  char *name = malloc(100);
  printf("Please enter the student name: ");
  scanf("%99s", name);  // 99+1 limit avoids buffer overflow

  return name;
}

or a variant to allocate exactly the good number of bytes, using the almost standard strdup string function:

char *get_name(void){
  char name[100];
  printf("Please enter the student name: ");
  scanf("%99s", name);

  return strdup(name);
}

Your struct should then hold a pointer instead of a buffer:

typedef struct{
  char *name;
  int id;
}student;

you need to free it when not used anymore

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
1

Jean-François Fabre's answer is so adequate. Alternatively, static keyword can be used. However, scanf()'s usage like is not recommended. You should limit the input size, scanf("%99s", name);, to prevent buffer overflow attacks.

char* get_name(void){
  static char name[100];
  printf("Please enter the student name: ");
  scanf("%99s", name);

  return name;
}
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
0

In the get_name() function name is declared as of char type not as char array.

char name;
scanf("%s", &name); 

Instead declare name as char array of some size. for.e.g

char name[20];
scanf("%s", name); /* &  is not needed as name itself address */

But then returning local array like return name; would cause undefined behavior. Better create the dynamic array & return it.

Or declare name as pointer variable & allocate memory for it & then scan the data from user.

char *name = malloc(SIZE); /* define the size */
scanf("%s",name); 
return name; /*returning dynamic array, catch with another pointer in calling function & free it once done */

Once you done with dynamic memory don't forget to free it by calling free(name).

Achal
  • 11,821
  • 2
  • 15
  • 37
0

name is a character, not a string.

You need to change the declaration to char name[MAXSTRING] or char *name = malloc(MAXSTRING). However, since you are returning name, you should return the address of something allocated on the heap instead of the stack. As a consequence, you should probably use the malloc.

Then, you won't have to give the address of name: scanf("%s", name) or even scanf("%20s", name) if you want to protect your code against a buffer overflow.

Finally, instead of returning a string, you could also take the name as an argument:

void get_name(char *name) {
    printf("Please enter the student name: ");
    scanf("%d", name);
}

and call it that way:

student s1;
get_name(s1.name);

That way, you don't need to allocate and free some memory.

Maxime Chéramy
  • 17,761
  • 8
  • 54
  • 75