0

I am writing a simple program to convert a number(+ve,32-bit) from binary to decimal. Here's my code:

int main()
{
    int n=0,i=0;
    char binary[33];
    gets(binary);
    for (i = 0; i < 33, binary[i] != '\0'; i++)
        n=n*2+binary[i]-'0';
    printf("%d",n);
}

If I remove binary[i]!='\0', then it gives wrong answer due to garbage values but if I don't it gives the correct answer. My question is: does the gets function automatically add a '\0' (NULL) character at the end of the string or is this just a coincidence?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
bufftowel
  • 45
  • 1
  • 8
  • 3
    `gets` is deprecated. Do not use it. – Christian Gibbons Feb 19 '19 at 18:07
  • may i know why is that? – bufftowel Feb 19 '19 at 18:08
  • 4
    See [Why the `gets()` function is too dangerous to be used — ever!](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-dangerous-why-should-it-not-be-used) – Jonathan Leffler Feb 19 '19 at 18:08
  • 1
    Using `gets()` is dangerous because it doesn't know how big the buffer is. If you enter 32 digits (or fewer) and a newline, your code would be 'OK'. If you enter more, or add spaces at either end, then you will run into problems. The `gets()` function was removed from C11 (a change forecast in TC3 — Technical Corrigendum 3 — in 2007). You should assume it causes your program to crash. (Note that a program using `gets()` was one of the bugs that allowed the Morris Internet Worm to escape in 1988.) – Jonathan Leffler Feb 19 '19 at 18:10
  • 3
    Re the behaviour: the `'\0'` is added at the end of the text you entered, not at the end of the array you defined. – Weather Vane Feb 19 '19 at 18:11
  • 3
    Note that the `for` loop condition `i < 33, binary[i] != '\0'` uses a comma operator which evaluates and discards the LHS (`i < 33`) and then produces the result of the RHS (`binary[i] != '\0'`). If the user types 64 digits, your loop will go accessing way beyond the end of the array. – Jonathan Leffler Feb 19 '19 at 18:17
  • 3
    Also, the ASCII NUL (single `L`) character is different from `NULL`. You should only use `NULL` in the context of pointers. On some systems, it is defined as `#define NULL ((void *)0)` and using that to assign to an `char` will often (but not necessarily) trigger a compiler warning. It depends on how fussy you set your compiler to be. – Jonathan Leffler Feb 19 '19 at 18:18
  • ok i will keep that in mind. – bufftowel Feb 19 '19 at 18:23
  • any modern C compiler will output a message about the function: `gets()`. You should always enable the warnings then fix those warnings. Suggest using `fgets()` (which has a different syntax, so read the MAN page) – user3629249 Feb 19 '19 at 20:02
  • @ChristianGibbons gets was removed in 2011. It was deprecated before that – M.M Feb 19 '19 at 20:25

2 Answers2

6

Yes it does, writing past the end of binary[33] if it needs to.

Never use gets; automatic buffer overrun.

See Why is the gets function so dangerous that it should not be used? for details.

Joshua
  • 40,822
  • 8
  • 72
  • 132
2

When gets was last supported (though deprecated) by the C standard, it had the following description (§ 7.19.7.7, The gets function):

The gets function reads characters from the input stream pointed to by stdin, into the array pointed to by s, until end-of-file is encountered or a new-line character is read. Any new-line character is discarded, and a null character is written immediately after the last character read into the array.

This means that if the string read from stdin was exactly as long as, or longer than, the array pointed to by s, gets would still (try to) append the null character to the end of the string.

Even if you are on a compiler or C standard revision that supports gets, don't use it. fgets is much safer since it requires the size of the buffer being written to as a parameter, and will not write past its end. Another difference is that it will leave the newline in the buffer, unlike gets did.

Govind Parmar
  • 20,656
  • 7
  • 53
  • 85