0
int prompt(const char *output_message, char *input, const int MAX_SIZE)
{
    printf("%s", output_message);

    int i = 0;
    char ch = '\0';

    while (1)
    {
        ch = (char)getchar();

        if (ch == '\n' || ch == EOF)
        {
            break;
        }
        else if (i < (MAX_SIZE - 1))
        {
            input[i++] = ch;
        }
    }

    input[i] = '\0';

    return i;
}

I wrote this function to get an input string input from the user. So getchar(), is going through the buffer until it reaches a newline or the end of the file. My question is does flushing the input buffer mean to move the FILE pointer(or whatever implementation is there) away from the currently written part in the buffer like I'm doing with getchar()? What does it actually mean to "flush the input buffer"?

sam_i_am
  • 23
  • 1
  • 6
  • Not related to the question you asked, but: you need to declare `ch` as type `int`, and you don't need the `(char)` cast when you call `getchar`. – Steve Summit Sep 26 '21 at 19:40
  • @SteveSummit But then I would have to type cast back when I use input[i++] = ch; so I don't think that's a good idea. – sam_i_am Sep 26 '21 at 19:53
  • I, on the other hand, think it's a *very* good idea, but if you don't believe me, here are several other questions asking about it: [1](https://stackoverflow.com/questions/39341213) [2](https://stackoverflow.com/questions/60332668) [3](https://stackoverflow.com/questions/35356322) [4](https://stackoverflow.com/questions/48870708) [5](https://stackoverflow.com/questions/31152974) [6](https://stackoverflow.com/questions/13694394) [7](https://stackoverflow.com/questions/32720934). You don't need any explicit casts when storing into your `input` array — who told you that? – Steve Summit Sep 27 '21 at 00:18
  • @SteveSummit The compiler gives me a warning. – sam_i_am Sep 27 '21 at 03:01
  • warning: implicit conversion loses integer precision: 'int' to 'char' [-Wimplicit-int-conversion] input[i++] = ch; – sam_i_am Sep 27 '21 at 03:11
  • What compiler are you using? That's a terrible warning. Probably every C program in existence assigns `int` to `char` for various reasons. It's a good thing to do far more often than it's dangerous. I would disable that warning if I were you. – Steve Summit Sep 27 '21 at 03:36
  • I was reading those links you posted and wow I didn't know how wonky it was. If I change ch to int, would this "input[i++] = (char)ch;" still be OK? The above if statement would check if it's EOF and since ch is an int, I shouldn't have to worry about the loop never-ending or the loop ending prematurely. – sam_i_am Sep 27 '21 at 03:52
  • Right. `ch` must be `int`, to avoid problems with `EOF`. Saying `(char)ch` is one way to work around the warning. But I would never write it that way, because I've been writing C code without that cast for 40 years. The warning is worthless, and should not be enabled, in my opinion. – Steve Summit Sep 27 '21 at 04:02

1 Answers1

1

"Flushing the input buffer" refers to the attempt to discard unwanted characters from the input stream so that they do not perturb later input calls.

In your code, it doesn't look like you'll have this problem, so flushing the input buffer should not be an issue for you.

The unwanted input issue typically occurs when you're doing input using scanf. scanf typically leaves the user's newline on the input buffer, but later calls to getchar or fgets (or even scanf) can be badly confused by this.

The problem with flushing the input is that there isn't really a good way of doing it. A popular although not recommended technique is to call fflush(stdin). That looks like it ought to be just the ticket, but the problem is that it's not well-defined and not guaranteed to work (although some programmers have found that it works well enough for them, on some platforms).

See this question and this question (maybe also this one) for much more on this issue.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
  • Gotcha, so after I call getchar() is the previous char still sitting in the input stream, or is it cleared? And from what I read, the standard is really against using fflush with stdin. – sam_i_am Sep 26 '21 at 19:52
  • I also wrote a function called scanf_flush that takes care of this problem. However, I think I want to rename "scanf_flush" to "prompt" and "prompt" to something like "prompt_c_str". Got any better name ideas? – sam_i_am Sep 26 '21 at 20:00
  • `getchar` *removes* characters from the input stream as it gives them to you. That's the way just about all input functions work (in any language). I would not call this "flushing"; it's just ordinary reading. Looking at the next character *without* removing it is considerably less usual, and usually has a name like "peek", as opposed to "get" or "read". (C, by the way, has no "peek" call at all. If you want to look at the next character but leave it on the input stream, you have to read it using `getchar`, then put it *back* on the input stream using `ungetc`.) – Steve Summit Sep 27 '21 at 00:06
  • So in summary: if you look at the next character without removing it, that's "peeking"; if you remove it without looking at it that's "flushing", and if you do both — look at it and remove it — that's "get", or ordinary reading. – Steve Summit Sep 27 '21 at 00:10
  • My recommendation for a function named `scanf_flush` is not to rename it, but to eliminate it. I believe it is not worth trying to flush input while calling `scanf`. If your use of `scanf` is not working, and the way to fix it seems to be to try to flush input, I believe the right solution is to use `scanf` some different way that doesn't require flushing, or to not worry about it (as I explain [here](https://stackoverflow.com/questions/2979209/using-fflushstdin/58884121#58884121)), or to [use something other than `scanf`](https://stackoverflow.com/questions/58403537). – Steve Summit Sep 27 '21 at 00:22
  • Wow that was a very detailed explanation, thank you. The reason why I made the function, to begin with, is if you read an int and then str the new line is still in the buffer causing the str to read the new line. So making the function ensured that nothing like that would happen. – sam_i_am Sep 27 '21 at 03:08
  • One last final question, let's just I read 10 characters in the input buffer. And for some reason, I want to go back 5 characters. Will that character still be sitting there like how when I free memory the value that was associated with that memory is still sitting there? – sam_i_am Sep 27 '21 at 03:18
  • *if you read an int and then str the new line is still in the buffer causing the str to read the new line* Of course. But my point is that flushing the newline is *not* your only option. If you read the string using `scanf`, you can arrange for it to skip the newline. Or, the other approach is, as I said, not to use `scanf` in the first place. In the long run, `scanf` is useless anyway. So spending time figuring out how to flush input to prop up `scanf`'s weaknesses is just a waste of time, in my opinion. – Steve Summit Sep 27 '21 at 03:23
  • *I read 10 characters in the input buffer. And for some reason, I want to go back 5 characters* No. There's not a good way to do that as far as `` is concerned. But if you read a whole line into your *own* buffer, you can move back and forth in that buffer at will. That's the sort of thing that several of [these answers](https://stackoverflow.com/questions/58403537) are talking about. – Steve Summit Sep 27 '21 at 03:27
  • Makes sense, but how else are you supposed to read an int from the user? Read it as a str then typecast it? – sam_i_am Sep 27 '21 at 03:28
  • I guess you haven't read [What can I use for input conversion instead of scanf?](https://stackoverflow.com/questions/58403537) yet. – Steve Summit Sep 27 '21 at 03:30
  • Awesome, thank you so much for everything I really appreciate all of your help! – sam_i_am Sep 27 '21 at 03:32