2
int main(){
    char str[10][50],temp[50];
    int lim,i,j;
    printf("Enter lim: ");
    scanf("%d",&lim);
    for(i=0;i<lim;++i){
        printf("Enter string[%d]: ",i+1);
        gets(str[i]);
    }

Here the str[0](Enter string[1]: ) can't be read. The reading starts from 'Enter string[2]: '(str[1]).

But if instead of lim, an integer is passed to loop as below, program executes correctly. What may be reason for this scenario ?

int main(){
    char str[10][50],temp[50];
    int lim,i,j;
    for(i=0;i<5;++i){
        printf("Enter string: ");
        gets(str[i]);

    }
stackphish
  • 143
  • 3
  • 8
  • 2
    `scanf` left a newline in the input stream. So the first `gets` just reads that newline. There are multiple dupes of this on SO – Support Ukraine Jun 15 '18 at 07:09
  • [may be related why-scanfd-does-not-consume-n-while-scanfc-does](https://stackoverflow.com/questions/13275417/why-scanfd-does-not-consume-n-while-scanfc-does) – Nahuel Fouilleul Jun 15 '18 at 07:10
  • 2
    Never, never, never use `gets`. It is so insecure and so prone to exploit by buffer overrun it has been completely removed from the C library in C11. If your professor suggests uses `gets`, run, don't walk, and get a new professor -- that one does not know what he is talking about. – David C. Rankin Jun 15 '18 at 07:10

2 Answers2

3

Your scanf() for the number has left a newline in the input stream, which will feed the first gets().

Have a look here for help:
http://sekrit.de/webdocs/c/beginners-guide-away-from-scanf.html
How to read / parse input in C? The FAQ

Also, you do not want to use gets() anymore.
Why is the gets function so dangerous that it should not be used?

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
Yunnosch
  • 26,130
  • 9
  • 42
  • 54
2

Firstly don't use gets() use fgets() instead. From the manual page of gets()

Never use gets(). Because it is impossible to tell without knowing the data in advance how many characters gets() will read, and because gets() will continue to store characters past the end of the buffer, it is extremely dangerous to use. It has been used to break computer security. Use fgets() instead.

Secondaly stdin is line buffered, when you use scanf() like scanf("%d",&lim); and press ENTER, the newline \n char is left into stdin stream that causes gets() to not to read str[0].

For e.g

for(i=0;i<lim;++i){

       printf("Enter string[%d]:\n ",i);    

       fgets(str[i],sizeof(str[i]),stdin);

}

Also note that when you use fgets() it will store \n into buffer at the end. If you don't want \n at the end of str[index] you have to remove it.

Also don't Forget to check the return value of fgets().

For e.g

char *ptr = NULL;

ptr=fgets(str[i],sizeof(str[i]),stdin);

 if( ptr != NULL && str[strlen(str[i])-1] == '\n'){

         str[strlen(str[i])-1] = '\0'; /* replace \n with \0 */

}

Achal
  • 11,821
  • 2
  • 15
  • 37
  • `scanf()` is not line buffered, `stdin` and terminal input are line buffered. Furthermore, `gets()` does read `str[0]`: it makes it en empty string precisely because there is a pending newline in `stdin`. Your proposed change does not fix the problem, the pending newline must be read manually for `fgets()` to read further input from the user. – chqrlie Jun 15 '18 at 07:18
  • It may also be worth explaining where the `'\n'` ends up when using `fgets` and how you may want to address removing it. – David C. Rankin Jun 15 '18 at 07:18
  • Quibble, but you should really validate the length is not zero before checking `length-1` (if the string is empty -- for whatever reason, you invoke undefined behavior). Better `size_t len = strlen (str); if (len && str[len-1] == '\n') {...}` – David C. Rankin Jun 15 '18 at 07:29
  • Yes true David. – Achal Jun 15 '18 at 07:31
  • No biggie, it's worth pointing out, I've been guilty of it on more than one occasion `:)` – David C. Rankin Jun 15 '18 at 07:33
  • Or I can suggest OP to check return value of `fgets()` as I shown `ptr!= NULL`. – Achal Jun 15 '18 at 07:37
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/173197/discussion-between-achal-and-david-c-rankin). – Achal Jun 15 '18 at 07:41