0

My code:

#include <stdio.h>
#include <math.h>
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        char a[10],b[10];
        puts("enter");
        gets(a);
        puts("enter");
        gets(b);
        puts("enter");
        puts(a);
        puts(b);
    }
    return 0;
}

Output:

1

enter 

enter

surya  (string entered by user)

enter

surya   (last puts function worked)
  • 7
    [The number of times you should use `gets()` in any program is zero.](https://stackoverflow.com/q/1694036/1679849) – r3mainer Apr 17 '20 at 10:54
  • 2
    @r3mainer That comment should be *the* answer to that question. – RobertS supports Monica Cellio Apr 17 '20 at 10:59
  • While I do agree with @r3mainer's comment, I would also suggest reading some book on the C language. ( K&R is best, [Beej' guide](http://beej.us/guide/bgc/html/single/bgc.html) is available for free. ) In particular, it won't hurt to get some understanding of strings and variables. In your case, `gets()` faithfully reads anything until user hits , and then `puts()`, well, writes that. ( All this putting aside possible issues with overflows, etc -- read e.g. any modern man page on `gets()` . ) – ジョージ Apr 17 '20 at 11:09

2 Answers2

4

How can I use “gets” function many times in C program?

You should never ever use gets() in your program. It is deprecated because it is dangerous for causing buffer overflow as it has no possibility to stop consuming at a specific amount of characters - f.e. and mainly important - the amount of characters the buffer, a or b with each 10 characters, is capable to hold.

Also explained here:

Why is the gets function so dangerous that it should not be used?

Specially, in this answer from Jonathan Leffler.

Use fgets() instead.


Also the defintion of a and b inside of the while loop doesn´t make any sense, even tough this is just a toy program and for learning purposes.

Furthermore note, that scanf() leaves the newline character, made by the press to return from the scanf() call in stdin. You have to catch this one, else the first fgets() thereafter will consume this character.


Here is the corrected program:

#include <stdio.h>

int main()
{
    int t;
    char a[10],b[10];

    if(scanf("%d",&t) != 1)
    {
        printf("Error at scanning!");
        return 1;
    }

    getchar();          // For catching the left newline from scanf().

    while(t--)
    {        
        puts("Enter string A: ");
        fgets(a,sizeof a, stdin);
        puts("Enter string B: ");
        fgets(b,sizeof b, stdin);

        printf("\n");

        puts(a);
        puts(b);

        printf("\n\n");
    }

    return 0;
}

Execution:

$PATH/a.out
2
Enter string A:
hello
Enter string B:
world

hello

world


Enter string A:
apple
Enter string B:
banana

apple

banana
3

The most important message for you is:

Never use gets - it can't protect against buffer overflow. Your buffer can hold 9 characters and the termination character but gets will allow the user to typing in more characters and thereby overwrite other parts of the programs memory. Attackers can utilize that. So no gets in any program.

Use fgets instead!

That said - what goes wrong for you?

The scanf leaves a newline (aka a '\n') in the input stream. So the first gets simply reads an empty string. And the second gets then reads "surya".

Test it like this:

#include <stdio.h>
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        char a[10],b[10];
        puts("enter");
        gets(a);        // !!! Use fgets instead
        puts("enter");
        gets(b);        // !!! Use fgets instead
        puts("enter");
        printf("|%s| %zu", a, strlen(a));
        printf("|%s| %zu", b, strlen(b));
    }
    return 0;
}

Input:

1
surya
whatever

Output:

enter
enter
enter
|| 0|surya| 5

So here you see that a is just an empty string (length zero) and that b contains the word "surya" (length 5).

If you use fgets you can protect yourself against user-initiated buffer overflow - and that is important.

But fgets will not remove the '\n' left over from the scanf. You'll still have to get rid of that your self.

For that I recommend dropping scanf as well. Use fgets followed by sscanf. Like:

if (fgets(a,sizeof a, stdin) == NULL)
{
    // Error
    exit(1);
}
if (sscanf(a, "%d", &t) != 1)
{
    // Error
    exit(1);
}

So the above code will automatically remove '\n' from the input stream when inputtin t and the subsequent fgets will start with the next word.

Putting it all together:

#include <stdio.h>
int main()
{
    int t;
    char a[10],b[10];
    if (fgets(a,sizeof a, stdin) == NULL)
    {
        // Error
        exit(1);
    }
    if (sscanf(a, "%d", &t) != 1)
    {
        // Error
        exit(1);
    }

    while(t--)
    {
        puts("enter");
        if (fgets(a,sizeof a, stdin) == NULL)
        {
            // Error
            exit(1);
        }
        puts("enter");
        if (fgets(b,sizeof b, stdin) == NULL)
        {
            // Error
            exit(1);
        }
        puts("enter");
        printf("%s", a);
        printf("%s", b);
    }
    return 0;
}

Input:

1
surya 
whatever

Output:

enter
enter
enter
surya 
whatever

Final note:

fgets will - unlike gets - also save the '\n' into the destination buffer. Depending on what you want to do, you may have to remove that '\n' from the buffer.

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63