Как исправить "игнорируемое возвращаемое значение: 'scanf'" код C6031 в Visual Studio

Я новичок в кодировании C (и кодировании в целом), поэтому я практиковался с некоторыми случайными программами. Предполагается, что он определяет стоимость транзитного билета (цены Translink Vancouver) в зависимости от возраста пользователя и желаемого количества "зон" (как далеко они хотели бы пройти). Я успешно скомпилировал его, но по какой-то причине, которую я не могу понять, функции scanf игнорируются. Как это исправить? Имейте в виду, что я занимаюсь кодированием всего несколько дней. Спасибо!

int main(void) {

int zones;
int age;
double price = 0.00;

printf("Welcome to TransLink cost calculator!\n\n");
printf("Please enter the desired number of zones (1, 2, or 3) you wish to travel: ");
scanf("%d", &zones);

if (zones < 1) {
    printf("Invalid entry\n");
    price = 0.00;
}

else if (zones > 3) {
    printf("Invalid entry\n");
    price = 0.00;
}

else if (zones == 1) {

    printf("Please enter your age: ");
    scanf("%d", &age);

    if (age < 0.00) {
        printf("Invalid Aage");
    }
    else if (age < 5) {
        price = 1.95;
    }
    else if (age >= 5) {
        price = 3.00;
    }
}

else if (zones == 2) {

    printf("Please enter your age: ");
    scanf("%d", &age);

    if (age < 0) {
        printf("Invalid Aage");
    }
    else if (age < 5) {
        price = 2.95;
    }
    else if (age >= 5) {
        price = 4.25;
    }
}

else if (zones == 3) {

    printf("Please enter your age: ");
    scanf("%d", &age);

    if (age < 0) {
        printf("Invalid Aage");
    }
    else if (age < 5) {
        price = 3.95;
    }
    else if (age >= 5) {
        price = 4.75;
    }
}

printf("The price of your ticket is: $%.2f + tax\n", price);

system("PAUSE");
return 0;
}

4 ответа

Здесь слишком много, чтобы оставлять комментарии.

Я использую версию Visual C, но она никогда не жалуется на возвращаемое значение из scanfне используется. Что это делает, чтобы жаловаться, чтоscanfявляется небезопасным и не рекомендуется, если это не так.

MS думает, что мне следует использовать его собственную "более безопасную" версию scanf_s что еще сложнее в использовании, а ИМО вовсе не безопаснее - потому что это не аналогичная замена, но требует других аргументов, и поэтому при ее использовании легко сделать ошибки.

Одна из последующих проблем заключается в том, что компилятор выдает предупреждение при каждом использованииscanf(и некоторые другие функции), которые скрывают другие предупреждения. Я справляюсь с этим, как советую, добавляя#define перед первым включением заголовка библиотеки.

#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>

Есть и другие вопросы, о которых предупреждает MS, и я на самом деле ставлю три #defines в начале каждого файла:

#define _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_DEPRECATE  
#define _CRT_NONSTDC_NO_DEPRECATE

#include <stdio.h>

И теперь соответствующие предупреждения легко увидеть.

Из документации scanf()(например, https://en.cppreference.com/w/c/io/fscanf)

Возвращаемое значение
1-3) Число успешно назначенных аргументов приема (которое может быть нулевым в случае сбоя сопоставления, произошедшего до того, как был назначен первый аргумент приема), или EOF, если сбой ввода происходит до того, как был назначен первый аргумент приема.

Вы игнорируете это возвращаемое значение.

Заменить

scanf("%d", &age);

по

int NofScannedArguments=0; /* Number of arguments which were
successfully filled by the most recent call to scanf() */

/* ...  do above once, at the start of your function */

NofScannedArguments= scanf("%d", &age);

/* check the return value to find out whether scanning was successful */
if(NofScannedArguments!=1) /* should be one number */
{
    exit(EXIT_FAILURE); /* failure, assumptions of program are not met */
}

... чтобы узнать, удалось ли сканировать. Не делать этого - плохая идея и заслуживает вашего предупреждения.

Если вы хотите более изящно обрабатывать сбои, например, снова запросите пользователя,
используйте цикл и прочтите http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html о подводных камнях, с которыми вы можете столкнуться..
Я не говорю, что вы НЕ должны использовать scanf, статья много объясняет об использовании scanf, пытаясь убедить вас не делать этого.

Я знаю, что это старый вопрос, и его несколько раз задавали в других темах.

Чтобы подавить отдельное предупреждение C6031, я применил функцию w/ (void).

Пример:

      double x;
(void)scanf("%lf", &x);

таким образом я могу «отметить», что намеренно игнорирую возвращаемое значение функции (=scanf). Это полезно для таких функций, как InitializeCriticalSectionAndSpinCount(), которая всегда завершается успешно и возвращает ненулевое значение, которое стоит безопасно игнорировать.

Кажется, лучше полностью подавить C6031.

Использование функций C++ для ввода НАСТОЛЬКО проще. Вместо scanf и printf можно использовать cin и cout, как показано ниже:

      #include <iostream>  // for cin and cout use

int main()
{
    int zones;

    std::cout << "Enter zones" << std::endl;  // endl is similar to \n
    std::cin >> zones;
    std::cout << "Your zones is " << zones << std::endl;
}
Другие вопросы по тегам