【问题标题】:scanf("%[^\n]s") works fine with normal variable but doesn't work with a structure variable in Cscanf("%[^\n]s") 适用于普通变量,但不适用于 C 中的结构变量
【发布时间】:2018-06-23 10:20:22
【问题描述】:

我正在使用 GCC 编译器

我也想扫描白色字符,所以我使用了scanf("%[^\n]s",&name),效果很好。

说代码是

void main(){
    char name[20];
    scanf("%[^\n]s",&name);
    printf("%s",name);
}

但是当我尝试将它与结构变量一起使用时,该语句不再起作用。

struct book { char name[20];};
main(){
    struct book buk[10];
    int i;
    for(i=0;i<3;i++)
    {
        printf("Enter name of book %d",i+1);
        scanf("%[^\n]s",&buk[i].name);}
    }

scanf 语句只是不执行。

但如果我使用简单的scanf("%s",&amp;name);,它就可以正常工作。 有人可以帮我解决这个问题吗?

【问题讨论】:

  • "简单的scanf("%s",&amp;name); 它工作得很好。" 它似乎工作得很好。 scanf("%s",&amp;name); 调用未定义的行为。 %s 需要 char*,而 &amp;name 不是。
  • 你有一个额外的s。你想要"%[^\n]",而不是"%[^\n]s"。 (但是正如用户 3121023 指出的那样,您确实想要 "%19[^\n]",或者可能是 " %19[^\n]"。或者可能完全跳过 scanf,并改用 fgets。)
  • 您应该检查来自scanf() 的返回值,以确保它符合您的预期。

标签: c structure scanf


【解决方案1】:

我使用了scanf("%[^\n]s",&amp;name),它运行良好?不,它运行不正常。阅读scanf()的手册页,上面写着

int scanf(const char *format, ...);

第一个参数是char* 类型,但&amp;name 不是char* 类型。

这个

char name[20]; 
scanf("%[^\n]s",&name);

应该是

scanf("%[^\n]",name);/* & is not needed as name itself address */

也应该只是"%[^\n]" 而不是"%[^\n]s"。正确的是

scanf(" %19[^\n]",name); /* giving space before % prevents reading extra characters */

另外最好使用fgets()。例如

 char *p = fgets(buk[i].name),sizeof(buk[i].name),stdin);
 if(p != NULL) {
      /* do some stuff */
 }

旁注,如果您使用的是fgets(),那么您应该注意fgets() 在缓冲区末尾存储\n这一事实。所以你可能想用\0替换那个\n,因为你可以使用strcspn()或者手动做。

编辑:请注意stdin 流是行缓冲的,即在scanf("%[^\n]",name); 换行符\n 停留在stdin 流中之后,如果您第二次再次扫描数据,它可能因不在name 中存储任何内容而失败,并且可能会调用未定义的行为。所以首先检查scanf()的返回值。

【讨论】:

  • 好点,您还应该解释在"%[^\n]" 之后的输入流中的换行符,如果在空行上,下一个"%[^\n]" 将失败。您使用 " %[^\n]" 的解决方案会跳过换行符和任何其他空格,但也会跳过任何空行,这不一定是预期的行为。
  • scanf() 的行为并非您所暗示的:它不会忽略下一个输入,它会失败并返回0,而目标数组保持不变,如果用户不检查返回值,可能会导致未定义的行为,这是常见的做法。
  • 感谢@chqrlie 已编辑。
猜你喜欢
  • 1970-01-01
  • 2020-05-04
  • 1970-01-01
  • 1970-01-01
  • 2020-01-09
  • 2014-04-19
  • 1970-01-01
  • 1970-01-01
  • 2012-12-23
相关资源
最近更新 更多