如何在使用结构指针时实现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一样工作