C 学校编程类问题(Visual Studio)

C 学校编程类问题(Visual Studio),c,windows,macos,visual-studio-2017,scanf,C,Windows,Macos,Visual Studio 2017,Scanf,我刚开始学习编程,在学校老师使用了Macbook和一个名为“X-Code”的程序,在家里我使用了windows和Visual Studio(2017)。 老师对什么是“setbuf”给出了0的解释,还说我们必须在VisualStudio中使用稍微不同的scanf。现在我在家里,完全无助。实际上,VS说最好试试scanf_s,我就这么做了,程序一直运行到我可以输入“操作”为止。输入前两个参数后,它停止,窗口自动关闭。你们谁能帮我一个忙,给我解释一下我不明白的事情 提前谢谢。 这是我写的代码 voi

我刚开始学习编程,在学校老师使用了Macbook和一个名为“X-Code”的程序,在家里我使用了windows和Visual Studio(2017)。 老师对什么是“setbuf”给出了0的解释,还说我们必须在VisualStudio中使用稍微不同的scanf。现在我在家里,完全无助。实际上,VS说最好试试scanf_s,我就这么做了,程序一直运行到我可以输入“操作”为止。输入前两个参数后,它停止,窗口自动关闭。你们谁能帮我一个忙,给我解释一下我不明白的事情

提前谢谢。 这是我写的代码

void main() {

    int a, b, c;
    char m;

    printf("Erstes Argument: ");
    scanf_s("%d", &a);

    printf("Zweites Argument: ");
    scanf_s("%d", &b);

    printf("Operation: "),
    //setvbuf(stdin,NULL); 
    scanf_s("%c", &m);

    if (m == '*') {
        c = a * b;
        printf("%d * %d = %d \n", a, b, c);
    }
    else {
        printf("Falsche Operation! \n");
    }

    return 0;
}

如果您想使用所有MS细微差别和不可移植的库调用,您可以这样做,但要知道,最终它会教您如何使用语言标准中未记录的函数进行编码

为此,还要了解C“语言”有两个主要组成部分:实际的语言本身(是什么使它成为C代码)和一个强制性的标准函数库(其中一些是您熟悉的,
printf
scanf
,等等)。您可以学习第一部分,即语言,并了解它是如何独立于附带的标准库工作的。最后,后者(库)为您提供了大量可以使用的操作,如果您严格遵守标准定义的操作,您的代码将更加健壮、可移植,并且任何熟悉该标准的C工程师都可以理解

无论如何,使用Microsoft选择的库扩展使您的程序“工作”的最小更改是:

#include <stdio.h>

// FIXED return type
int main() {

    int a, b, c;
    char m;

    printf("Erstes Argument: ");
    scanf_s("%d", &a);

    printf("Zweites Argument: ");
    scanf_s("%d", &b);

    printf("Operation: ");

    // FIXED arguments passed to setvbuf
    setvbuf(stdin, NULL, _IONBF, 0);

    // FIXED arguments passed to scanf_s
    // FIXED added white space consumption prior to character read
    scanf_s(" %c", &m, 1);

    if (m == '*') 
    {
        c = a * b;
        printf("%d * %d = %d \n", a, b, c);
    }
    else 
    {
        printf("Falsche Operation! \n");
    }

    return 0;
}
#包括
//固定返回类型
int main(){
INTA、b、c;
charm;
printf(“Erstes参数:”);
scanf_s(“%d”和“&a”);
printf(“茨威茨论点:”);
scanf_s(“%d”和“b”);
printf(“操作:”);
//已修复传递给setvbuf的参数
setvbuf(标准输入,空,0);
//已修复传递给scanf_s的参数
//修正了读取字符前增加的空白消耗
scanf_s(“%c”&m,1);
如果(m=='*')
{
c=a*b;
printf(“%d*%d=%d\n”,a、b、c);
}
其他的
{
printf(“Falsche操作!\n”);
}
返回0;
}
不依赖MS isms的适当、符合标准的版本可以是:

#include <stdio.h>

int main() {

    int a, b, c;
    char m;

    printf("Erstes Argument: ");
    scanf("%d", &a);

    printf("Zweites Argument: ");
    scanf("%d", &b);

    printf("Operation: ");
    scanf(" %c", &m);

    if (m == '*') 
    {
        c = a * b;
        printf("%d * %d = %d \n", a, b, c);
    }
    else 
    {
        printf("Falsche Operation! \n");
    }

    return 0;
}
#包括
int main(){
INTA、b、c;
charm;
printf(“Erstes参数:”);
scanf(“%d”和“&a”);
printf(“茨威茨论点:”);
scanf(“%d”和“b”);
printf(“操作:”);
scanf(“%c”、&m);
如果(m=='*')
{
c=a*b;
printf(“%d*%d=%d\n”,a、b、c);
}
其他的
{
printf(“Falsche操作!\n”);
}
返回0;
}
如果没有功能禁用宏
\u CRT\u SECURE\u NO\u WARNINGS
,您将收到来自MS的三条警告,说明您应该使用其“更安全”的功能。虽然他们勇敢地尝试使我们的程序更安全,但我们可以很容易地争辩说,如果工程师仅仅学会如何正确地编写更安全的代码会更好


最后,您的代码没有完成。您应该检查IO呼叫是否成功。现在假设用户为
a
b
提供的输入是正确解析的有效整数。如果不是这样,代码将继续运行,最终使用不确定的数据进行计算,并在过程中调用未定义的行为。有记录的返回代码是有原因的。使用它。

实际上VS说最好尝试scanf_是的,VisualStudio推出了不可移植的、特定于Microsoft的语言扩展,其中包含关于C标准要求的函数被“弃用”的误导性消息。请参阅:“由于与规范存在大量偏差,Microsoft实施无法被视为符合要求或可移植。”另请参阅您可以阅读有关MSVC 2017库函数的内容
setbuf
。你的老师可能和我有不同的观点:微软想要统治世界,并警告你不要使用标准功能。请坚持使用C标准函数。在任何
#include
指令之前,我在MSVC代码中放置以下三行:
#定义#CRT(安全)无警告
#定义#CRT(安全)无弃用
。可悲的是,一些所谓的“更安全”版本根本不安全,或者有安全的方法使用标准功能。尤其是它们的
scanf_s
系列使用起来比标准函数更为棘手错误,因为它需要一个长度参数:“与
scanf
wscanf
不同,
scanf\us
wscanf\us
要求为
c
c
s
s
类型的所有输入参数指定缓冲区大小,或包含在
[]
。缓冲区大小(以字符为单位)将作为附加参数在指向缓冲区或变量的指针后立即传递。“最好在家用计算机上安装x-code,不要使用MS for C编程。这是一个一般性的建议。使用包含空格的
“%c”
很好,它将使用任何前导空格,OP可能不知道这些空格是由大多数格式说明符自动完成的,但不是由
“%c”
自动完成的。