以下代码与scanf()
完美匹配,但我想输入字符和空格。我已经尝试了gets()
和fgets()
(下面评论过),但它不起作用(它跳转到循环中的下一次迭代,并在{{1}使用的名称输入的输出期间显示空白(NULL) })。知道怎么做吗?
PS:我已经尝试了fgets()
样本程序,它的工作正常。但是在使用结构指针时我很困惑。
fputs()
输出:
#include <stdio.h>
#include <stdlib.h>
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; i<tot; i++) {
printf("%d)Id = ", i+1);
scanf("%d", &info->Id);
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; i<tot; i++) {
printf("%d)Id = %d\n%d)Name = %s\n", i+1, info->Id, i+1, info->Name);
info++;
}
return 0;
}
答案 0 :(得分:4)
问题来自&#34;%d&#34; 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<tot; i++) {
printf("%d)Id = ", i+1);
scanf("%d\n", &info[i].Id)); // <-- store input in current info record
// and eat up the line terminator
printf("%d)Name = ", i+1);
fgets(info[i].Name, // <-- idem
sizeof(info[i].Name), // fgets will guarantee no buffer overflow
stdin);
}
printf("\nDisplaying details:\n");
for(i=0; i<tot; i++) {
printf("%d)Id = %d\n%d)Name = %s\n", i+1, info[i].Id, i+1, info[i].Name);
对于scanf / fgets,在你的情况下(使用&#34;%s&#34;格式为scanf),他们都应该读取输入,直到输入新行,包括空格。
scanf ("%s")
确实会停在第一个空白区域。如果你想要整条线,最简单的方法就是使用fgets。如果您真的想使用scanf,则需要使用"%[^\n]%*c"
之类的语法。
如果用户输入超过20个字符,要确保缓冲区不会溢出,您可以
"%19[^\n]%*c"
作为scanf
格式(&#39; \ 0&#39;终止符需要第20个字符),或fgets
作为缓冲区大小传递20(fgets
负责终结器,它最多可读取19个字符,以便能够添加&#39; \ 0&#39;溢出)。当然,您应该使用sizeof
来计算最大缓冲区大小,例如:
fgets(info[i].Name, sizeof(info[i].Name), stdin);
因此,如果您决定将缓冲区大小更改为50个字符,则不必修改该值。
答案 1 :(得分:2)
首先,您的代码中存在严重错误。
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);
答案 2 :(得分:0)
scanf()
的行与fgets()
之间的行getchar()
像这样
scanf("%d",&(info->Id));
getchar();
答案 3 :(得分:-3)
我遇到了同样的问题!实际上,我来到这个页面来获得解决方案然后我记得缓冲区!所以这就是我解决它的方式:
[...]
cout << "\nType the name: " ;
fflush(stdin); (you always have to clean the buffer before saving chars to a variable)
gets(pers.nom);
[...]
干杯!! 附: cin和cout来自C ++,但像scanf和printf
一样工作