C代码适用于Visual Studio 2013,但2017年不适用?

时间:2018-03-09 20:49:20

标签: c compilation visual-studio-2017

今天我在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,因为即使没有它也无法解决问题。

2 个答案:

答案 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);