1

In the following simple code the input of the first gets is not showing up. Any help please?

int main()
{
    int x;
    char tmp[1];
    char anystr[10], srchstr[1];

    printf("Enter an string : ");
    gets(anystr);

    printf("Enter any character you want to search in input string: ");
    gets(srchstr);

    printf("anystr : %s\n",anystr);
    printf("anystr : %c\n",anystr[0]);
    printf("srchstr : %c\n",srchstr[0]);

    return 0;
}

The Output is null for first fgets string anystr:

Enter an string : hello
Enter any character you want to search in input string: h
anystr : 
anystr : 
srchstr : h
Yunnosch
  • 26,130
  • 9
  • 42
  • 54
MRZ
  • 23
  • 6
  • 3
    WTF are you using `gets` - It is bad news, deprecated .... – Ed Heal Apr 22 '18 at 18:27
  • `char srchstr[1]` is not large enough to hold the one character you are entering *plus* the NUL terminator. – Jonathon Reinhart Apr 22 '18 at 18:28
  • an array of size 1 is a single `char` -- how would you ever expect this to hold any "string" (except the empty string of course)? –  Apr 22 '18 at 18:29
  • Title says "second" is lost. Question says "first" is lost. Which is it? – Yunnosch Apr 22 '18 at 18:29
  • 2
    It's a perfect demonstration **why** `gets()` doesn't exist any more. obviously, `srchstr` is placed in memory directly before `anystr`, so the second `gets()` overwrites the first character of `anystr` with a `0` -- intending to terminate `srchstr`, but instead making `anystr` the empty string. At least no nasal demons for you (yet, unless you enter even longer lines). **don't ever use `gets()`**. –  Apr 22 '18 at 18:31
  • @FelixPalmen I was already editing when your comment appeared and I did not notice, so I did not actually take your know how. Hope you do not mind anyway. – Yunnosch Apr 22 '18 at 18:44
  • 3
    See [Why is `gets()` so dangerous that it should never, ever be used?](https://stackoverflow.com/questions/1694036). – Jonathan Leffler Apr 22 '18 at 18:44
  • @Yunnosch and I was already about to UV your answer, but am busy looking for a good pair of duplicates to close this mess :D Jonathan just added the link to the one I already found, still missing a good canonic one on string terminators :) –  Apr 22 '18 at 18:46
  • @FelixPalmen Why not make this one the canonic? It is a very nice tiny example, practically tailor-made to fit the purpose... – Yunnosch Apr 22 '18 at 18:48

2 Answers2

2

You have a problem because you have undefined behaviour.
The UB is caused by having second gets() write beyond the 1-char array srchstr. What is written beyond is the terminator '\0'.
See the gets() docu: http://en.cppreference.com/w/c/io/gets

No answer to this question should omit to mention (using Jonathan Lefflers nice link):
Why is the gets function so dangerous that it should not be used?

That is it. UB and dangerous. Done. End of answer.

Well....
One speculation of which specific nasal demon is flying around would be:
strchr is located right before anystr. This means that the one beyond access hits right the first char inside anystr.
I.e. it terminates that other string right after zero characters.
I.e. it makes it empty.
Printing it therefor has no output, even though the second character is still from the perviously written string.

Yunnosch
  • 26,130
  • 9
  • 42
  • 54
  • Thanks yunnosch. Increasing the length of srchstr solved the problem. – MRZ Apr 22 '18 at 19:51
  • @MRZ, Don't use `gets()` at all. Instead, use `fgets()` (remembering, of course, that the input buffer will contain the trailing '\n' which will need to be removed, probably by a call to `strspn()` – user3629249 Apr 23 '18 at 22:07
  • @user3629249 Did you notice the link by Jonathan Leffler which explains in detail what probably is the background of your comment? I fail to see your point because of the existence of that link inside my answer. Or did you execlusively address MRZ and just wanted to stress the link? In that case I totally agree. – Yunnosch Apr 24 '18 at 04:47
1

Don't use gets() as pointed here in man 3 fges

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.

Use fgets() like

fgets(anystr,sizeof(anystr),stdin);

Also char srchstr[1]; should be char srchstr; as you are asking in printf Enter any character you want to search in input string:

And to scan srchstr use scanf(" %c",&srchstr);

you may want something like

int main(void ) {
        char anystr[10],srchstr;
        printf("Enter an string : ");
        fgets(anystr,sizeof(anystr),stdin);/*use fgets instead of gets */

        printf("Enter any character you want to search in input string: ");
        scanf(" %c",&srchstr);/* give the space before %c to avoid buffering problem */

        printf("anystr : %s\n",anystr);
        printf("anystr : %c\n",anystr[0]);
        printf("srchstr : %c\n",srchstr);

        return 0;
}
Achal
  • 11,821
  • 2
  • 15
  • 37