0

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!

3
  • 2
    A "string" in C in fact is a 0-terminated char-array. The 0 needs to go somewhere. Commented Feb 17, 2018 at 14:01
  • 1
    You need to increase the size of each char array by (at least) 1 to make room for the \0 character. Commented Feb 17, 2018 at 14:16
  • Note that this could also cause some nasty side effect. Because there is no space for the '\0' after the year array, this '\0' is still written in the next memory byte after the end of the class. Depending on what is stored there, you could end up corrupting your data. Commented Feb 17, 2018 at 15:13

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

8 Comments

@alk.: Yes precisely what you said. Edited.
Again about structure: From the question it is quiet obvious that the OP has no idea about what makes a "string" in C. Your question talks about 0s in the beginning, which would most likely not make any sense to the OP, and only at the end you explains what it is all about. So this is the exception to the rule we found some hours ago. No rule without exception ... ;-)
Thank you I understood what you want to say. :-) @coderredoc
An old "trick" we used to have back in my C programming days is to write string length like this: char year[4+1];, that way it was even clearer when the content size was intended to be.
"... writer I am" I am sure you improve every day.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.