如何在使用结构指针时实现gets()或fgets()?

下面的代码与scanf()运行完美,但我想输入字符和空格。 我已经尝试了gets()fgets() (在下面评论),但它不起作用(它跳转到循环中的下一次迭代并在输出fgets()使用的Name输入期间显示空白(NULL)。 知道怎么做吗?

PS:我用样本程序试过fputs() ,工作正常。 但是在使用结构指针时我很困惑。

 #include  #include  struct details { uint Id; char Name[20]; }; int main() { int tot, i; struct details *info; printf("Enter no. of details to be stored = "); scanf("%d", &tot); info = (struct details *)malloc(tot*sizeof(struct details)); for(i=0; iId); printf("%d)Name = ", i+1); fgets(info->Name, 20, stdin); //How to make fgets() work?? //scanf("%s", &info->Name); //works fine with scanf() info++; } for(i=0; i<tot; i++) { --info; } printf("\nDisplaying details:\n"); for(i=0; iId, i+1, info->Name); info++; } return 0; } 

输出:

 [xyz@xyz:Temp] $ ./fgets_Struct Enter no. of details to be stored = 2 1)Id = 111 1)Name = 2)Id = 222 2)Name = Displaying details: 1)Id = 111 1)Name = 2)Id = 222 2)Name = [xyz@xyz:Temp] $ 

问题来自“%d”scanf。 它不消耗行终止符,因此下一次读取会将其解释为空行。

您的info分配也是错误的。 分配大小应该用的不是info的大小,而是info 指向的元素的大小。

 printf("Enter no. of details to be stored = "); scanf("%d\n", &tot); // <-- must consume end of line here info = (struct details *)malloc(tot* sizeof(*info)); // <-- use size of the pointed object, not the pointer 

此外,修改您的info指针是不必要和危险的。
这样的事情会更简单,更安全

 for(i=0; i 

至于scanf / fgets,在你的情况下(给scanf给出“%s”格式), 他们都应该读取输入,直到输入一个新行,包括空格。

编辑:我在这里说错了,抱歉,感谢chux纠正我。

scanf ("%s")确实会在第一个空格处停止。 如果你想要整条线,最简单的方法就是使用fgets。 如果你真的想使用scanf,你需要一个像"%[^\n]%*c"这样的语法。

如果用户输入超过20个字符,要确保缓冲区不会溢出,您可以

  • 使用"%19[^\n]%*c"作为scanf格式('\ 0'终止符需要第20个字符),或者
  • 使用fgets作为缓冲区大小传递20( fgets负责终结器,它最多可读取19个字符,以便能够添加'\ 0'而不会溢出)。

当然,您应该使用sizeof来计算最大缓冲区大小,例如:

 fgets(info[i].Name, sizeof(info[i].Name), stdin); 

因此,如果您决定将缓冲区大小更改为50个字符,则不必修改该值。

首先,您的代码中存在严重错误。

 info = (struct details *)malloc(tot*sizeof(info)); 

sizeof(info)返回4或8(取决于平台,32位或64位),但与结构大小无关。 所以你要为指针分配内存,但是正在为你的struct使用那个空间。 将数据写入此将覆盖内存中的其他数据(尽管可能不是在这个简单的示例中),因为您分配的字节太少。 你想要使用的是sizeof(struct details) ,它将返回24。

现在给你的输入问题。 基本上,scanf和gets不应该像这样一起使用。 问题是scanf会读取您键入的内容,直到您按下return,这不包括在内。 在此之后调用gets时,它会看到此返回并立即返回一个空字符串。 如果您将所有输入调用更改为gets,它将完美运行。 例:

 char test[256]; printf("Enter no. of details to be stored = "); gets(test); tot = atoi(test); 

对于ID和fgets()scanf()之间放置getchar()这样的行

 scanf("%d",&(info->Id)); getchar(); 

我有同样的问题! 实际上,我来到这个页面来获得解决方案然后我记得缓冲区! 所以这就是我解决它的方式:

 [...] cout << "\nType the name: " ; fflush(stdin); (you always have to clean the buffer before saving chars to a variable) gets(pers.nom); [...] 

干杯!! PS cin和cout来自C ++,但像scanf和printf一样工作