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):
上一篇: 在viewWillDisappear期间隐藏UINavigationController的UIToolbar: