Школьные занятия по программированию (Visual Studio) - PullRequest
0 голосов
/ 06 сентября 2018

Я только начал изучать программирование, и в школе учитель использовал Macbook и программу под названием «X-Code», а дома у меня есть окна с Visual Studio (2017). Учителя объяснили, что такое setbuf, и также сказали, что мы должны использовать scanf немного по-другому в Visual Studio. Теперь я дома и совершенно беспомощен. На самом деле VS сказал, что лучше попробовать scanf_s, так я и сделал, и программа работает, пока я не смогу ввести «Operation». После того, как я введу первые два аргумента, он останавливается, и окно закрывается. Может ли кто-нибудь из вас помочь мне и дать немного объяснения о вещах, которые я не понимаю?

Заранее спасибо. Вот код, который я написал

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;
}

1 Ответ

0 голосов
/ 06 сентября 2018

Если вы хотите использовать все нюансы MS и непереносимые вызовы библиотек, вы можете это сделать, но понимаете, что в итоге он учит вас кодировать, используя функции, которые не документированы в стандарте языка.

Для этого также следует понимать, что «язык» C имеет два основных компонента: сам язык (что делает его кодом C) и обязательную сопровождающую библиотеку стандартных функций (некоторые из которых вам знакомы *) 1003 *, 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;
}

Правильная, стандартная версия, не зависящая от 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;
}

Без макроса отключения функции _CRT_SECURE_NO_WARNINGS вас встретит множество предупреждений от MS о том, что вы должны использовать их «более безопасные» функции. Несмотря на то, что они отважились попытаться сделать наши программы более безопасными, можно легко поспорить, что было бы лучше, если бы инженеры просто научились правильно писать более безопасный код.

Наконец, ваш код не готов. Вы должны проверять свои IO звонки на успех. Прямо сейчас вы предполагаете, что пользователь предоставил в качестве входных данных для a и b, они правильно проанализированы, действительные целые числа. Если это не так, ваш код работает, в конечном итоге используя неопределенные данные для расчета и вызывая неопределенное поведение в процессе. scanf имеет документированный код возврата по причине. Используйте это.

...