0

I have a simple question (I think so) about fflush() in C++. Every time I write some code to input string in C++, I have to try many many ways because My program caused Error every time. So I will ask a very simple question. My code here:

void main()
{
    int n;
    string str;
    cin >> n;
    fflush(stdin);
    fflush(stdin);
    getline(cin, str);
    cout << n << endl << str << endl;
}

and the compiler does not allow me to enter the string str, how can I do that now?

And I don't want to talk about cin.ignore() here, just about only fflush()

  • 3
    Flushing is done on the other side of the stream, where the data is outputted. On the reading side, you can't force the other side to flush its buffer. – Ted Lyngmo Jul 08 '20 at 07:51
  • 3
    https://en.cppreference.com/w/cpp/io/c/fflush – anastaciu Jul 08 '20 at 07:51
  • 2
    What would it mean to flush an input stream? This seems like an [xy-problem](http://xyproblem.info/) – Lukas-T Jul 08 '20 at 07:52
  • When taking another look at your program I think I've figured out what you want to do: You want to read `n` without having to press **return**, right? If can't be done using standard C++. You'll have to use a portable library or platform specific functions for that. – Ted Lyngmo Jul 08 '20 at 07:58
  • You don't flush input streams. That discards unknown amounts of characters, something you never want to do. – cmaster - reinstate monica Jul 08 '20 at 07:59
  • so how can I fix the code, all I want is to enter the integer n and string str and print it to the console later – babylearnmaths Jul 08 '20 at 08:03
  • Btw, trial and error is not an efficient way to program. Reading the `man` pages of the involved C library functions is. That will tell you precisely what your calls do, and give you the means to construct your code to do exactly what you want. – cmaster - reinstate monica Jul 08 '20 at 08:05
  • If you look at the C standard for [7.21.5.2 The fflush function](http://port70.net/~nsz/c/c11/n1570.html#7.21.5.2), `fflush()` is only defined for *output* steams... (and Microsoft has a non-standard implementation) – David C. Rankin Jul 08 '20 at 08:08
  • How you fix your code? Well, you start by not mixing uses of `cin` and `stdin` for a start. They are two separate bits of machinery consuming characters from a single source, but using their distinct internal buffers. Either use the C library functions (`fscanf()` and friends), or the C++ stream library (`cin >> stuff`), only. This alone will improve your experience thousandfold. – cmaster - reinstate monica Jul 08 '20 at 08:09
  • 1
    @babylearnmaths You fix your code by using `ignore`, but you don't want to talk about that. Seriously do some research. This question comes up 1000s of times. – john Jul 08 '20 at 08:25
  • Because in my code, when I use ```cin.ignore(100,'\n')```, I have to enter the string twice to continue the program, BUT, when i remove it, I can not enter the string anymore. – babylearnmaths Jul 09 '20 at 04:25

1 Answers1

3

flushing stdin is undefined behavior, since fflush is meant to be called on an output stream. This is taken from the C standard [7.21.5.2]/2:

int fflush(FILE *ostream);

If stream points to an output stream or an update stream in which the most recent operation was not input, the fflush function causes any unwritten data for that stream to be delivered to the host environment to be written to the file; otherwise, the behavior is undefined.

you can find the standard C here in the link below, go to page 139

ANSI/ISO 9899-1990

Adam
  • 2,820
  • 1
  • 13
  • 33
  • so how can I edit my code without using cin.ignore()? – babylearnmaths Jul 08 '20 at 07:57
  • 1
    What do you want to do? What do you thought `fflush(stdin)` was doing? Why did you use it? – KamilCuk Jul 08 '20 at 07:58
  • i think fflush(stdin) clear the buffer, so I am wrong, right? – babylearnmaths Jul 08 '20 at 08:01
  • I can't find a mention of UB in the `fflush()` man page. I do find the thing about discarding an unknown, uncontrollable amount of characters from the input, but not immediately UB as far as the C library is concerned. Can you provide a source that declares `fflush(stdin)` to be UB? – cmaster - reinstate monica Jul 08 '20 at 08:03
  • @cmaster-reinstatemonica - see the c standard here page 139. chrome-extension://oemmndcbldboiebfnladdacbdfmadadm/https://www.pdf-archive.com/2014/10/02/ansi-iso-9899-1990-1/ansi-iso-9899-1990-1.pdf – Adam Jul 08 '20 at 08:07
  • @cmaster-reinstatemonica - see my answer please. i have updated it to includes the link to the standard. – Adam Jul 08 '20 at 08:10
  • 1
    @TedLyngmo - thanks i have added another link for ansic standard. see my answer. thanks for editing my answer. appreciate it. – Adam Jul 08 '20 at 08:14
  • 1
    @Adam chrome-extension://oemmndcbldboiebfnladdacbdfmadadm - wtf? Anyways, the part behind the following slash works, thanks :-) This is the C89/90 standard, my manpages are newer. So it seems like the definition of `fflush(stdin)` has indeed changed from "is UB" to "discards an unknown, uncontrollable amount of characters". Good to know. – cmaster - reinstate monica Jul 08 '20 at 08:15
  • @cmaster-reinstatemonica No, it's still UB. See the top link in the answer. It's to the C17 proposal. It should be _very_ close to what's in the current C18 standard. – Ted Lyngmo Jul 08 '20 at 08:16
  • @TedLyngmo Funny. So either there's some other standard (POSIX?) that defines the behavior, or my libc defines the behavior, or my manpage is wrong. I wonder which. – cmaster - reinstate monica Jul 08 '20 at 08:19
  • @cmaster-reinstatemonica Well, it's undefined according to the standard so if an implementation chooses to actually define the behavior it should be documented that making code that depends on that behavior is not portable. I wouldn't trust `man` pages to go into that much detail. The behavior was first specified in POSIX.1-2008 according to my `man` page. – Ted Lyngmo Jul 08 '20 at 08:24
  • @cmaster-reinstatemonica yes, POSIX defines fflush for seekable input streams (stdin is only seekable if redirected from a file. For a terminal stdin, it's still undefined). In practice, e.g. linux glibc fflush does nothing for terminal stdin because it swallows the error returned by lseek. – Cubbi Jul 08 '20 at 15:04