Почему мы не можем напрямую инициализировать переменную в структуре с помощью scanf? - PullRequest
0 голосов
/ 10 января 2019

Вместо того, чтобы инициализировать мою переменную в структуре с числовым значением 0, я попытался использовать scanf так, чтобы он непосредственно считывал мои входные значения. Это не работает, но я не могу понять, почему?

Мне было интересно, может ли это быть связано с тем, что использование & (p1.first) недопустимо, поскольку пространство памяти не было выделено? Если это так, единственный ли способ обновить значение моих переменных структуры через переписывание операторов scanf после инициализации, например, в приведенном ниже коде с комментариями?

#include <iostream>

using namespace std;

typedef struct {
  int first;
  int second;
} score;

int main() {
  score p1 = {
    p1.first = scanf("%d", &(p1.first)),
    p1.second = 0,
  };

  /* I know the following works:
  score p1 = {
    p1.first = 0,
  };
  scanf("%d", &(p1.first));
  */

  printf("%d", p1.first);
}

Когда ввод равен 2, я ожидал получить также 2, но независимо от значения ввода, которое я пробовал, printf печатает 1.

Ответы [ 2 ]

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

Вы можете инициализировать элементы из выражений . Выражение - это кусочек кода, который что-то оценивает. Кусок кода, который является вызовом функции, оценивает то, что возвращает вызов функции.

scanf не возвращает нужного значения, но количество успешно проанализированных аргументов (прочитайте документацию !) . Это не то, что вы хотите использовать. Затем вы попытались присвоить члену имя в слоте scanf "Out Параметр", но это не работает, потому что (a) объект еще не существует, и (b) вы буквально собираетесь инициализировать член из другого значения, потому что (c) параметр out не влияет на то, что выражение вычисляет.

Короче говоря, это не может работать. Вы можете заключить вызов в новую особую функцию, которая возвращает то, что вам нужно:

#include <cstdio>

struct score {
  int first;
  int second;
};

int ReadANumber()
{
   int number;

   const int r = std::scanf("%d", &number);
   if (r > 0 && r != EOF)
     return number;

   // some fallback, or you could throw an exception!
   return -1;
}

int main() {
  score p1 = { ReadANumber(), 0 };
  printf("%d", p1.first);
}

( живая демоверсия )

Обратите внимание, что я также исправил ваш заголовок, удалил назначения в инициализаторе (странно; работает по непонятным причинам, но не делаю этого), исключил определение вашего класса и удалил using namespace std как нам это не нравится.

& hellip; или придерживайтесь рабочего решения, которое у вас есть в ваших комментариях (хотя это исключает объявление p1 как const!).

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

scanf возвращает количество проверенных элементов. В данном случае, как вы описали свой конкретный вход, это всегда 1. Вот откуда берется 1.

...