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

I'm working on program which input looks as follows:

3.14 (it's variable stored in union)
4 (number of calls)
int (asked types to return)
long
float
double

On output should i get:
1078523331
1078523331
3.140000
0.000000

Full instruction to this task
My program works except on double case: instead of giving me any output program gives me none. Can anyone explain me why? Here is my code.

#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")] ='';//removing newline
  }

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

}

You do not allow sufficient space in array types for a six-character string such as "double" , because you need an extra byte for the terminator. Because you have used fgets() in a reasonable way, however, you have saved yourself from overrunning the bounds of that array -- fgets() just stops reading after the fifth character of "double", and appends a terminator. Therefore, what actually gets stored is "doubl" . Naturally, that compares different from "double" , so no corresponding output is produced.

  • In the first place, you should increase CHARLENGTH to at least 7. Doing so will take care of your immediate problem.

  • You should also consider adding a final else clause inside your loop that prints out a diagnostic message in the event that none of the other cases is satisfied. Such a message could have clued you in to what's going on.

  • for robustness, you might consider making sure to read and discard any trailing junk on the type lines; as it is, even trailing whitespace after one of the shorter type names will screw up your matching.

  • Perhaps it's respondent to the exercise as it is, but your program would be a lot more user friendly if it prompted for each input item.


  • Three Four quick observations:

    0) As a minimum, the main function should be: int main(void).

    1) Because C strings are defined as an array of char terminated with NULL, the string "double" requires a buffer with space for 7 char to contain it.

    |d|o|u|b|l|e||    //includes NULL char termination
    

    Change

    #define CHARLENGTH 6   
    

    to

    #define CHARLENGTH 7  
    

    2) Because it is not clear from the cmd line prompts in the running program what items are to be entered, if one of the string types , eg "double", is not entered, the line:

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

    will not do as it is intended. Suggest adding some printf statements with instructions for what to enter for all 3 entries per line.

    3) types is not initialized before use.
    This can be addressed by simply initializing like this:

    memset(types, 0, SIZE*CHARLENGTH);   
    

    or even simpler:

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

    A comparison of what the memory looks like by the time it gets to the fgets statement, uninitialized, or initialized (by either method): ![在这里输入图片描述

    链接地址: http://www.djcxy.com/p/90308.html

    上一篇: 在viewWillDisappear期间隐藏UINavigationController的UIToolbar:

    下一篇: 对于存储为union的数据,printf在调用double变量后不会输出