存储为 union 的数据上的 Printf 在调用 double 变量后没有输出

Printf on data stored as union gives no output after called for double variable

我正在编写输入如下所示的程序:

3.14(它是联合存储的变量)
4(调用次数)
int(要求类型为 return)

浮动

输出时我应该得到:
1078523331
1078523331
3.140000
0.000000

Full instruction to this task
我的程序在双重情况下工作:没有给我任何输出程序,而是给我 none。谁能解释我为什么?这是我的代码。

#include <stdio.h>
#include <string.h>
#define SIZE 1000
#define CHARLENGTH 6
union Data {
  int i;
  long long l;
  float f;
  double d;
};
int main(){
  union Data x;
  char types[SIZE][CHARLENGTH];
  int n;
  scanf("%f",&x.f);
  scanf("%d",&n);
  for(int i = 0;i<=n+1;i++){
    fgets(types[i],CHARLENGTH,stdin);
    types[i][strcspn(types[i],"\n")] ='[=10=]';//removing newline
  }

  for(int i = 1;i<=n+1;i++){
    if(strcmp(types[i], "int") == 0){
      printf("%d\n",x.i);
    }
    else if(strcmp(types[i], "long") == 0){
      printf("%lli\n",x.l);
    }
    else if(strcmp(types[i], "float") == 0){
      printf("%f\n",x.f);
    }
    else if(strcmp(types[i], "double") == 0){
      printf("%lf\n",x.d);
    }
  }

}

您不允许在数组 types 中为 six-character 字符串(例如 "double")提供足够的 space,因为您需要一个额外的字节作为终止符。但是,因为您以合理的方式使用了 fgets(),所以您避免了超出该数组的边界——fgets() 只是在 "double" 的第五个字符之后停止读取,并追加终结者。因此,实际存储的是"doubl"。自然和"double"比较不一样,所以没有产生相应的输出。

  • 首先,你应该将CHARLENGTH增加到至少7。这样做可以解决你眼前的问题。

  • 您还应该考虑在循环中添加一个最终的 else 子句,以便在满足其他情况的 none 时打印出诊断消息。这样的消息可能会让您了解正在发生的事情。

  • 为了健壮性,您可以考虑确保阅读并丢弃 type 行中的任何尾随垃圾;事实上,即使在较短的类型名称之一之后尾随 whitespace 也会搞砸你的匹配。

  • 也许它是对练习的回应,但如果它提示每个输入项,你的程序会更加用户友好。

三个四个快速观察:

0) main 函数至少应为:int main(void)

1) 因为 C 字符串被定义为以 NULL 结尾的 char 的数组,所以字符串 "double" 需要一个 space 的缓冲区来容纳 7 char它。

|d|o|u|b|l|e|[=10=]|    //includes NULL char termination

改变

#define CHARLENGTH 6   

#define CHARLENGTH 7  

2) 因为从运行程序中的cmd行提示不清楚要输入哪些项目,如果字符串types之一,例如"double",未输入,行:

fgets(types[i],CHARLENGTH,stdin);  

不会按预期进行。建议添加一些 printf 语句,并说明每行 3 个条目的输入内容。

3) types使用前未初始化
这可以通过像这样简单地初始化来解决:

memset(types, 0, SIZE*CHARLENGTH);   

或更简单:

char types[SIZE][CHARLENGTH] = {0}; 

比较内存在到达 fgets 语句时的样子,未初始化或已初始化(通过任一方法):