今天我在VS 2013
大学写了一个代码并且它有效。我通过电子邮件发送给自己在家里试试。它不适用于VS 2017
。幸运的是,我有VS 2013
,它确实有效。为什么会这样?
以下是VS 2017
上失败的代码部分:
#include<stdio.h>
#include<conio.h>
#include<string.h>
typedef struct{
char name[50];
char pos[50];
double sel[12];
double annpay;
}sluj;
typedef struct{
int num;
sluj per[100];
}firma;
firma f;
int main(){
int i, j;
do{
printf("Enter number of employees\n");
scanf("%d", &f.num);
} while (f.num < 1 || f.num > 100);
for (i = 0; i < f.num; i++){
printf("Enter the name of employee:\n");
fflush(stdin);
fgets(f.per[i].name, 50, stdin); //it acts like this row doesnt exist
//and prints the text below
printf("Enter the position of employee:\n");
fgets(f.per[i].pos, 50, stdin); //basiclly the same thing as above, but on different
//structure member (both are defined char)
//and it works here!
for (j = 0; j < 12; j++){
printf("Enter salary for %d month\n", j+1);
scanf("%lf", &f.per[i].sel[j]);
}
}
for (i = 0; i < f.num; i++){
f.per[i].annpay = 0;
for (j = 0; j < 12; j++){
f.per[i].annpay += f.per[i].sel[j];
}
}
for (i = 0; i < f.num; i++){
if (f.per[i].annpay > 6000){
printf("\n%s %lf", f.per[i].name, f.per[i].annpay);
}
}
return 0;
}
我不认为问题出在fflush
,因为即使没有它也无法解决问题。
答案 0 :(得分:0)
scanf()
和fgets()
无法很好地协同工作。 scanf()
会查看受雇人数,提交\n
仍然会被缓存,并会提交给fgets()
。 fflush()
不适用于管道。
E.g。使用linux和glibc可以获得相同的行为
$ ltrace ./a.out > /dev/null
puts("Enter number of employees") = 26
__isoc99_scanf(2
"%d", 6295680) = 1
fflush(0x7f7c6811c9e0) = 0
puts("Enter the name of employee:") = 28
fgets("\n", 50, 0x7f7c6811c9e0) = 0x601088
puts("Enter the position of employee:") = 32
没有很好的方法来结合这两个功能;使用例如fgets()
将员工数量读入字符串并稍后进行转换。
答案 1 :(得分:0)
代码的问题是scanf()
将'\n'
作为工件留在stdin
中。
混合scanf()
和fgets()
是不明智的。
使用scanf()
的程序无法保护输入错误的输入。如果以员工人数输入字母,它会挂起。
使用fflush()
无济于事。
fflush()
通常仅用于output
流。其目的是清除(或刷新)输出缓冲区并将缓冲的数据移动到控制台(如果是stdout
)或磁盘(如果是文件输出流)。
根据C标准,使用fflush(stdin)
是未定义的行为。
然而,在某些编译器上,例如VS2013
,#34;工作&#34;。这已在VS2017
中更改。
剩余'\n'
的快速解决方法如下:
do{
printf("Enter number of employees\n");
scanf("%d", &(f.num));
} while (f.num < 1 || f.num > 100);
int c;
c = getchar();
if(c == EOF)
return -1; // END OF PROGRAM
if (c!='\n')
ungetc(c, stdin);