fgets不等待用户输入

3
在给定的代码中,fgets没有等待输入。
我尝试使用scanf,但它会出现异常错误(Exception thrown at 0x0F74DDF4 (ucrtbased.dll))。我正在使用Visual Studio 2015调试我的代码。有人能解释一下为什么fgets没有等待输入吗?
#include<stdio.h>
#include<stdlib.h>
#include<process.h>

//GLOBAL-VARIABLE DECLARTION
#define MAX 1000

//GLOBAL-STRUCTURES DECLARATION
struct census
{
char city[MAX];
long int p;
float l;
};

//GLOBAL-STRUCTURE-VARIABLE DECLARATION
struct census cen[] = { 0,0,0 };

//USER-DEFINED FUNCTION
void header();

void header()
{
printf("*-*-*-*-*CENSUS_INFO*-*-*-*-*");
printf("\n\n");
}

//PROGRAM STARTS HERE
main()
{   
//VARIABLE-DECLARATION
int i = 0, j = 0;
//int no_of_records = 0;

//FUNCTION CALL-OUT
header();

printf("Enter No. of City : ");
scanf_s("%d", &j);

printf("\n\n");

printf("Enter Name of City, Population and Literacy level");
printf("\n\n");

for (i = 0;i < j;i++)
{
    printf("City No. %d - Info :", i + 1);
    printf("\n\n");

    printf("City Name :");
    fgets(cen[i].city, MAX, stdin);
    printf("\n");

    printf("Population : ");
    scanf_s("%d", &cen[i].p);
    printf("\n");

    printf("Literacy : ");
    scanf_s("%f", &cen[i].l);
    printf("\n");
}

//TERMINAL-PAUSE
system("pause");
}

@user3121023 有没有办法修复这个问题? - Eddy
@user3121023 我想使用fgets,但除了scanf之外,还有其他方法可以用来获取整数或浮点数输入吗? - Eddy
3
尝试使用fgets()将内容存入一个单独的字符数组中,然后使用sscanf()从中解析出数据。 - jamieguinan
1
你不能只是简单地将scanf替换为scanf_s;如果你使用了%s%c%[格式,这在想要模拟fgets时很可能会出现,你必须为每个格式在scanf_s中提供一个最大缓冲区大小。但我同意@jamieguinan的观点:对于交互式输入,始终使用两步方法:首先读取一行,然后从该行读取数据。 - M Oehm
2
scanf_s("%f", &cen[i].l); 不会读取紧随数字后面的 '\n'。接下来的 fgets(cen[i].city, MAX, stdin); 会读取这个字符 '\n'。建议不要使用 scanf() - chux - Reinstate Monica
显示剩余2条评论
2个回答

3
当你输入城市数量并按下 Enter 键时,scanf 不会从输入读取换行字符。然后,fgets 尝试读取但找到换行符,并立即停止。
不要使用 scanf 读取数字,先使用 fgets 读入字符串,然后使用 sscanf(或strtol/strtof/strtod)将其转换为数字。
char temp[LIMIT];
if(fgets(temp, LIMIT, stdin)) {
    if(sscanf(temp, "%d", &j) == 1) {
        // Ok
    }
    else {
        // Handle sscanf error
    }
}
else {
    // Handle fgets error
}

谢谢你的帮助,我非常感激 :) - Eddy

2
我通常使用fgetssscanf。在顶部声明它:
char line[MAX];

然后使用fgets函数获取一行,再使用sscanf函数将其解析为整数值。

printf("Enter No. of City : ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%d", &j);

l的类似模式

printf("Literacy : ");
fgets(line, sizeof(line), stdin);
sscanf(line, "%f", &cen[i].l);

顺便说一下,如果你在j中使用一个大于3的值,你将会溢出你的cen]\数组,但这是一个单独的问题。 - jamieguinan
而且如果我们能够像@user694733那样检查返回值就好了。我的示例只是对原始版本进行了简单修改,应该适用于正常输入。 - jamieguinan
请问你能告诉我为什么当我使用大于3的值作为j时会发生溢出吗? - Eddy
@Eddy,当你在方括号中声明cen[]时没有指定大小,编译器会根据{}中的项目数量来确定大小,而你有3个零。你可以声明为cen[10],并处理多达10个或更多。为了安全起见,在循环之前你可以加上一个if测试,如果j大于数组的大小,则跳出/返回/退出。 - jamieguinan
我弄明白了,Jamie,不过还是谢谢你的回复 :) - Eddy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接