Bhushan Mendhe
Bhushan Mendhe

Reputation: 23

Structure null character(\0) issue with strings in C programming Language

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

Answers (1)

user2736738
user2736738

Reputation: 30936

In , 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 scanf1 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

Related Questions