2

I've got a very simple program that just takes two unsigned int inputs, and then goes through a for loop reading out each number below 9 as:

input 1 : output one

input 2 : output two

etc. and above 9 it outputs whether it is even or odd.

All goes fine except for when I call std::flush, it does not flush the buffer to the screen, however std::endl does. With the code as it is below, I get no output, however by changing flush to endl I do get an output. Why is this? I tried looking it up and all I could find slightly relevant was this Calls to flush cout are ineffective which said the problem was that a /r was being inserted, but I can't see how that could be the case here since I can see all the outputs don't have that.

#include <iostream>

enum integerState{belowTen,aboveNine};
enum parity{even,odd};

integerState process_integer(unsigned int n);
parity even_or_odd(unsigned int n);

int main(){
    unsigned int lowerLim,upperLim;
    std::cin >> lowerLim >> upperLim;
    for (unsigned int i=lowerLim;i<=upperLim;++i){
        process_integer(i);
    }

    return 0;
}

integerState process_integer(unsigned int n){

    switch(n){
        case 1: std::cout << "one" << std::flush;                   return belowTen;
        case 2: std::cout << "two" << std::flush;                   return belowTen;
        case 3: std::cout << "three" << std::flush;                 return belowTen;
        case 4: std::cout << "four" << std::flush;                  return belowTen;
        case 5: std::cout << "five" << std::flush;                  return belowTen;
        case 6: std::cout << "six" << std::flush;                   return belowTen;
        case 7: std::cout << "seven" << std::flush;                 return belowTen;
        case 8: std::cout << "eight" << std::flush;                 return belowTen;
        case 9: std::cout << "nine" << std::flush;                  return belowTen;
        default: 
        if(even_or_odd(n)==even){ std::cout << "even" << std::flush; return aboveNine;}
        if(even_or_odd(n)==odd){  std::cout << "odd"  << std::flush; return aboveNine;}
        return aboveNine;
    }
}

parity even_or_odd(unsigned int n){
    return (n%2==0 ? even:odd);
}

I'm using g++ if that matters.

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
  • 1
    How can you tell it's not working? When the program ends, all output will be flushed, so you can't tell if it's flushing in the middle or between each number. – Barmar Jul 30 '17 at 22:26
  • 1
    I tried your program, I got output. – Barmar Jul 30 '17 at 22:27
  • @Barmar because it does not flush at any point including when the program ends. without std::endl there is no output to the console. – John Cunningham Jul 30 '17 at 22:41
  • Can not reproduce. Your code works for me. I get output as expected. – Galik Jul 30 '17 at 22:56
  • 3
    `flush` just ensures the data is send out of the C++ program; the host environment might do its own line buffering – M.M Jul 30 '17 at 23:28

1 Answers1

0

The std::flush does the same thing as the fflush(FILE*) command. It empties the buffer of the corresponding file to the OS. How the OS reacts is rather unspecified.

Under Unices, it will generally work as expected. However, there are cases where it will still not flush to the screen. For example, if you use less (and probably more), the tool prints a line only after it received the '\n' character.

Under MS-Windows MS-DOS console, I think there is a lot of magic. That console does not work according to expected specification as found under Unices. It is likely to need the "\r\n" sequence to work properly. Newer versions work well with just '\n'. Flushing often doesn't work. Instead you need to use a totally unbuffered connection to the console (and I don't remember how you do that).

In Unices, the open(2) command accepts flags which include O_DIRECT and O_SYNC not only prevent buffering, but require the write(2) function to return only once all the data was written out by the device. Whether that works with a console, I am not 100% sure. But it would worth a try.

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156