为什么我们不能使用scanf直接在struct中初始化变量?

时间:2019-01-10 16:05:01

标签: c++ struct scanf

我没有使用数值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 :(得分:4)

scanf返回扫描的项目数。在这种情况下,您描述特定输入的方式始终为1。这就是1的来源。

答案 1 :(得分:2)

您可以从表达式初始化成员。表达式是一些计算结果的代码。一段调用函数的代码将评估该函数返回的内容。

scanf不会返回您想要的值,而是成功解析(读取the documentation!)的参数数量的计数。那不是您要使用的。然后,您尝试在scanf的“ out parameter”插槽中命名该成员,但这不起作用,因为(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);
}

live demo

注意,我也更正了您的标头包括,删除了初始化程序中的分配(很奇怪;出于不可思议的原因起作用,但不这样做),对C类定义进行了De-C处理并删除了{{ 1}},因为我们不喜欢这样。

…或坚持评论中使用的可行解决方案(尽管这排除了将using namespace std声明为p1!)。