带有%s的scanf仅返回字符串的第一个字符

时间:2018-05-16 17:30:51

标签: c

这是我的主要功能

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

  return name;
}

我初始化我的结构

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

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

但我得到的回报是我输入的字符串的第一个字符。 MAXSTRING在我的student.h中定义为

#define MAXSTRING 20

我很确定我必须以某种方式修改我的名字变量,但我尝试了很多东西并且没有工作。 在这种情况下使用fgets也更好吗?

4 个答案:

答案 0 :(得分:2)

你必须提供一个char 数组,而不是filterValue: string; modelChanged: Subject<string> = new Subject<string>(); constructor() { this.modelChanged .debounceTime(500) // you can change time .distinctUntilChanged() // emit only when value is different from previous value .subscribe(value => { this.filterValue = value; // perform filter }); } changed(text: string) { this.modelChanged.next(text); } 上的指针。然后你不能将本地数组返回到外部作用域,所以我建议你分配缓冲区:

char

或使用几乎标准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; } 字符串函数准确分配好字节数的变体:

strdup

然后你的struct应该保存一个指针而不是缓冲区:

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

  return strdup(name);
}

你不再使用时需要typedef struct{ char *name; int id; }student;

答案 1 :(得分:1)

Jean-FrançoisFabre的答案非常充分。或者,可以使用static关键字。但是,不建议使用scanf()的用法。您应该限制输入大小scanf("%99s", name);,以防止buffer overflow attacks

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

  return name;
}

答案 2 :(得分:0)

get_name()函数name声明为char类型而不是 char数组

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

而是将name声明为某个大小的char数组。 for.e.g

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

但是返回像return name;这样的本地数组会导致未定义的行为。更好地创建动态阵列&amp;把它归还。

或者将name声明为指针变量&amp;为它分配内存&amp;然后扫描用户的数据。

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 */

完成动态记忆后,请不要忘记通过拨打free(name)来释放它。

答案 3 :(得分:0)

name是一个字符,而不是字符串。

您需要将声明更改为char name[MAXSTRING]char *name = malloc(MAXSTRING)。但是,由于您要返回name,因此应该返回堆上分配的内容的地址而不是堆栈。因此,您应该使用malloc

然后,如果您想保护代码免受缓冲区溢出,则不必提供namescanf("%s", name)scanf("%20s", name)的地址。

最后,您还可以将名称作为参数:

,而不是返回字符串
void get_name(char *name) {
    printf("Please enter the student name: ");
    scanf("%d", name);
}

然后这样称呼:

student s1;
get_name(s1.name);

这样,你就不需要分配和释放一些记忆。