Пользователь помещает float в целочисленную переменную - PullRequest
0 голосов
/ 22 января 2019

Я использую gcc компилятор в Linux Ubuntu. Вот мой вопрос: я запутался, почему моя программа делает это. Почему он пропускает остальные мои scanf заявления, когда я ставлю поплавок. Я знаю, что вы не хотите помещать число в целое число, но почему оно это делает. Разве это не отрубает десятичную дробь и почему она помещает большие числа в переменные. Может кто-нибудь объяснить, пожалуйста? П.С. Я знаю, как это исправить, я просто хочу знать, почему он это делает.

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main() {
int i = 0;
int gamesPlayed = 0;
int goals[gamesPlayed];
int totalGoals = 0;
float avg = 0;

printf("How many games have you played? ");
scanf(" %d", &gamesPlayed);

for (i=0; i < gamesPlayed; i++)
{
    printf("How many goals did you score in game %d? ", i+1);
    scanf(" %d", &goals[i]);
    totalGoals += goals[i];
    printf("%d\n", totalGoals);
}

avg = ((float)totalGoals / gamesPlayed);
printf("Total Goals: %d\n", totalGoals);
printf("Avg: %.2f\n", avg);


return 0;
}   

Ошибка:
Сколько игр вы играли? 2,6 2.000000

Сколько голов вы забили в игре 1? 1863382920

Сколько голов вы забили во второй игре? 1863415686

Всего голов: 1863415686

Avg: 931707840.00

Ответы [ 2 ]

0 голосов
/ 22 января 2019

Эта очень упрощенная программа показывает, как вы можете решить проблему:

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>

// Read an integer value from the user
// returns false if input stream cannot be read (usually EOF)
// Any non digit characters are discarded:
// Examples:
// "123abc" => 123
// "123.456" => 123
// "" => 0
// "abc" => 0

bool ReadIntFromUser(int *value)
{
  char inputbuffer[100];

  if (fgets(inputbuffer, sizeof inputbuffer, stdin))
  {
    *value = (int)strtoul(inputbuffer, NULL, 10);
    return true;
  }
  else
    return false;
}


int main(void) {
  int x = - 1;

  while (ReadIntFromUser(&x))
  {
    printf("Input was %d\n", x);
  }
}

Улучшение ReadIntFromUser оставлено читателю в качестве упражнения.

0 голосов
/ 22 января 2019

При вводе 2.6 первый scanf прочитает 2 и оставит .6 во входном потоке.

Следующее scanf увидит. , который нельзя преобразовать в целое число.Следовательно, scanf возвращается и оставляет goals[i] неинициализированным.Входной поток будет по-прежнему содержать .6 , так что точно так же происходит снова и снова в цикле.

Затем вы используете неинициализированную переменную (и) для вычисления среднего и, следовательно, в конечном итогес "странными" значениями.Примечание. Использование неинициализированных переменных - неопределенное поведение.

Обратите внимание, что проблема не имеет ничего общего с float .Проблема в том, что входные данные содержат символ, который не может быть преобразован в целое число.Ввод, например 2HelloWorld6 , даст вам тот же результат.

Вам необходимо проверить значение, возвращаемое scanf, например:

if (scanf(" %d", &goals[i]) != 1)
{
    // Ups - could not scan an integer

    ... add error handling here ...
}

КСТАТИ: Рассмотрим чтение ввода пользователем сfgets и выполните сканирование с помощью sscanf.В большинстве случаев это намного проще, чем использовать scanf, потому что вы не окажетесь в ситуации, когда какой-либо символ застрянет во входном потоке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...