Scanf赢得';t扫描结构内部数据

Scanf赢得';t扫描结构内部数据,c,struct,C,Struct,我需要帮助 不管我输入什么,我都会得到相同的输出,就像程序不读取scanf的输入一样,有什么想法吗 我试图分别获取输入,以分割扫描,因此我将获得8个扫描。 但是没有运气 如果你能帮我指出我做错了什么,我将不胜感激 struct point{ double x; double y; }pt1,pt2,pt3,pt4; struct rect{ struct point pt1; struct point pt2; struct point pt3

我需要帮助

不管我输入什么,我都会得到相同的输出,就像程序不读取scanf的输入一样,有什么想法吗

我试图分别获取输入,以分割扫描,因此我将获得8个扫描。 但是没有运气

如果你能帮我指出我做错了什么,我将不胜感激

 struct point{
  double x;
  double y;
 }pt1,pt2,pt3,pt4;

 struct rect{
      struct point pt1;
      struct point pt2;
      struct point pt3;
      struct point pt4;
 };

  int main()
 {
    struct rect new_screen={
       scanf("%f,%f",&new_screen.pt1.x,&new_screen.pt1.y),
       scanf("%f,%f",&new_screen.pt2.x,&new_screen.pt2.y),
       scanf("%f,%f",&new_screen.pt3.x,&new_screen.pt3.y),
       scanf("%f,%f",&new_screen.pt4.x,&new_screen.pt4.y),
    };
       printf("the middle between (%.2f,%.2f) and (%.2f,%.2f) is ",new_screen.pt1.x,new_screen.pt1.y,new_screen.pt3.x,new_screen.pt3.y);
       print_point(middle(new_screen.pt1,new_screen.pt3));
   return 0;
 }



    struct point middle(struct point pt1, struct point pt2)
    {
        struct point tmp = {((pt1.x+pt2.x)/2),((pt1.y+pt2.y)/2)};
        return tmp;
    }
    void print_point(struct point pt)
    {
        printf("(%.2f,%.2f)",pt.x,pt.y);
    }

     output 
     the middle between (2.00,2.00) and (0.00,0.00) is (1.00,1.00)

这里是初始化

struct rect new_screen = {
   scanf("%f,%f",&new_screen.pt1.x,&new_screen.pt1.y),
   scanf("%f,%f",&new_screen.pt2.x,&new_screen.pt2.y),
   scanf("%f,%f",&new_screen.pt3.x,&new_screen.pt3.y),
   scanf("%f,%f",&new_screen.pt4.x,&new_screen.pt4.y),
};
。。。不会做你认为它会做的事
scanf
返回单个整数(有关返回值的含义,请参阅其手册页),但您的结构包含
struct point
字段。这总共是8次翻倍,4次调用
scanf
。由于初始化在C中的工作方式,您可以省略某些字段的大括号和初始值设定项。因此,这是令人遗憾的有效代码。但是它只初始化
new_screen.pt1
new_screen.pt2
(四次调用
scanf
初始化四个双精度)。你扫描到的东西会立即被覆盖。最后两个点不是用大括号初始化的,所以它们应该用零初始化,再次覆盖可能扫描到它们的任何内容

长话短说,假设所有
scanf
调用都没有失败(我们忽略了格式说明符的问题),您基本上写了以下内容:

struct rect new_screen = {
  { 2, 2 },
  { 2, 2 },
  { 0, 0 },
  { 0, 0 }
};
错误较少的初始化是:

struct rect new_screen;
scanf("%lf,%lf",&new_screen.pt1.x,&new_screen.pt1.y);
scanf("%lf,%lf",&new_screen.pt2.x,&new_screen.pt2.y);
scanf("%lf,%lf",&new_screen.pt3.x,&new_screen.pt3.y);
scanf("%lf,%lf",&new_screen.pt4.x,&new_screen.pt4.y);
它不会检查
scanf
是否成功(这就是为什么它的错误更少的原因),但它不会使用
scanf
的返回值践踏
new\u屏幕的内容。我还修复了格式说明符(您使用了
%f
,但是
double
变量需要
%lf

上述错误也证明了在编译时启用警告并解决它们是多么重要。例如,当我用
gcc-pedantic errors-Wall-Wextra
编译代码时,我得到了以下警告:

警告:格式“%f”要求参数类型为“float*”,但参数2的类型为“double*”[-Wformat=]
scanf(“%f,%f”,&new\u screen.pt1.x和new\u screen.pt1.y),
警告:初始值设定项周围缺少大括号[-w缺少大括号]
struct rect新屏幕={
警告:“struct rect”[-Wmissing字段初始值设定项]的字段“pt3”缺少初始值设定项
};

养成在启用警告的情况下编译的习惯,并解决这些问题,直到生成没有编译器诊断。

您正在使用
%f
格式读取
双值。这是未定义的行为(
%f
用于
float
类型;
%lf
用于
double
)。现代编译器通常会警告您这一点;如果您的编译器没有,请找到打开警告的选项,或者找到更好的编译器。请始终在编译器中启用警告。对于GCC,您应该添加
-Wall-Wextra-Wpedantic
。这将向您显示许多警告。逗号上有很好的标记。我认为新手程序员需要更多的解释;“这很微妙,”乔纳坦利弗勒-好建议。我试图在一次编辑中进一步阐述这一点,希望足以让新手理解这一点。我不知道要深入研究它有多深,所以对新手来说是不可能的。我不知道它是否太详细,但我可能会建议初始值设定项等效于
struct rect new_screen={{2,2},{2,2},{0,0},{0,0}scanf()
调用返回2(如果格式字符串是固定的),这些返回值覆盖结构的前四个元素,并且在
scanf()
调用设置值后,其他字段用零初始化。因此,从标准输入读取的数据被初始化删除。我辩论了是否在初始化器中编写
2.0
而不是
2
;懒惰使它们成为整数。@JonathanLeffler-编写等价的初始值设定项是一个极好的主意。我在信中加了这个。谢谢大家!@乔纳坦利弗勒——不管投票与否,这些都是很好的建议。所以还是谢谢你:)