Reputation: 23
Is the below issue happening because of null character. 'Yes/No'. Please explain why.
First code
#include<stdio.h>
struct date{ char day[2]; char month[2]; char year[4];
}current_date;
void main(){
printf("Enter day: ");
scanf("%s",current_date.day);
printf("Enter month: ");
scanf("%s",current_date.month);
printf("Enter year: ");
scanf("%s",current_date.year);
printf("\nEntered date is:
%s/%s/%s",current_date.day,current_date.month,current_date.year)
}
Input:
If I enter 17,02,1998 respectively for each scan.
Output:
Entered date is: 17021998/021998/1998
Second code for the same input when I just change the array length in structure.
#include<stdio.h>
struct date{ char day[3]; char month[3]; char year[5];
}current_date;
Rest the whole code is same.
Output
Entered date is: 17/02/1998
Please explain me this. Thank you in advance!
Upvotes: 0
Views: 407
Reputation: 30936
In c, a string is not an intrinsic type. A C-string is the convention to have a one-dimensional array of characters which is terminated by a null-character, by a '\0'
.
Using that knowledge it should be
struct date{ char day[3]; char month[3]; char year[5];
Otherwise scanf
1 won't be able to store the \0
within the array and it would be undefined behavior if you try to get 2
digit input (for day
or month
or 4
digit year by using %s
format specifier) with it - because scanf
will try to write it beyond the array and that would be Undefined Behaviour.
The scanf
usage would be
if(scanf("%2s",current_date.day)!=1){
fprintf(stderr,"Error in input\n");
exit(EXIT_FAILURE);
}
The way you defined your structure - would give you 1
digit month, 1
digit day and 3
digit year if you store the corresponding \0
also. That is not what you want. In C
strings are realized using nul terminated char
array - scanf
stores them. That's why in my case I have used %2s
- so that the remaining space is there for storing \0
.
1 Here note one thing from reference under %s
format specifier
matches a sequence of non-whitespace characters (a string) If width specifier is used, matches up to width or until the first whitespace character, whichever appears first. Always stores a null character in addition to the characters matched (so the argument array must have room for at least
width+1
characters).
Note: As pointed by Simon Berthiaume in comment -
You can write string length like this:
char year[4+1];
, that way it is clear what the content size is intended to be. For example in this case it is 4 digit year that you wanted.
Upvotes: 1