Thread: Newbie Question - fflush(stdin) & fpurge(stdin) on Mac and PC

  1. #1
    Registered User
    Join Date
    Feb 2006
    Location
    Sydney, Australia
    Posts
    40

    Newbie Question - fflush(stdin) & fpurge(stdin) on Mac and PC

    Hello,

    This is my first post here. So, firstly, let me say "Hi", I expect that I'll be a pretty regular visitor here in future, I certainly need the help and it's my hope that, some time in the future, I will be in a position to return the favour.

    In the mean time though...

    I am pretty much a rank newbie to C (I am currently doing a part time beginner's C course and I am in week 4 of 18) so I apologise in advance to all you veteran C coders out there who are no doubt preparing to roll your eyes and say to yourself, "Is this guy is thick or what?". I throw myself on the mercy of the forum and plead newbiness in the first degree.

    On to my specific question...

    After reading the forum FAQ and searching for posts on this topic, it seems that the common consensus is that using fflush(stdin) is a no-no (although, since my current knowledge base is so narrow, I don't fully understand the reason). However, I think that the fact that it's use is discouraged partially answers my question - but not all of it - so I hope no one minds if I lay out my problem.

    If anyone could help me make some sense out of it or even just point me in the direction of some clarifying documentation, I'd be extremely grateful. I don't expect people to hand me answers on a platter and I'm happy to put in the spade work, but I just have no idea where to even start on this one and my lack of background knowledge is a huge hindrance. In short, I am completely stumped.

    On to the issue at hand...

    BACKGROUND
    Everyone in my class, except me, is using Windows based machines (WinXP or 98) but, since I have a PowerBook G4 (1.5Ghz, 100GB HD, 1GB RAM), I am running MacOSX 10.4.4. Both platforms are using GCC to compile code so, from what little I know (or thought I knew) about compliers, I figured that there should be no difference, code-wise, between the two. However, after today, I am not so sure.

    I am also using Xcode v2.2 as an IDE but I also use emacs and GCC in a terminal session for short and/or simple programs, which is most of the code I have written so far.

    As I said, I'm 4 weeks into an 18 week C course (ie. plain vanilla C, not C++, Objective C or C#) and today I bumped up against what seemed to me to be a very strange problem. While compiling an in-class example program, I came across the fflush(stdin) function for the first time. The relevant section of the code follows...

    THE CODE

    Code:
    #include <stdio.h>
    
    int main(void)
    {
      int num1, num2, ans;
      char arithOp;
      ans=0;
      printf("Enter number 1 --> ");
      scanf("%d", &num1);
      printf("Enter number 2 --> ");
      scanf("%d", &num2);
      printf("Enter an operator (+, - or *) --> ");
    
    /*The program is supposed to pause for user input here but doesn't unless fflush is replaced by fpurge on the following line*/
    fflush(stdin);
    scanf("%c", &arithOp);
    ...the rest of the code goes on to do calculations and display the output but is not relevant to the problem.

    THE PROBLEM
    As indicated by the comment line in the code above, the program is supposed to pause and wait for user input after each prompt (ie. at each scanf function). This works fine the first 2 times but, when the third comes along (right after the fflush(stdin) function), it just rolls right through and doesn't wait for user input. Of course, as you will have realised, it doesn't get an entry for that variable so assumes a blank and gives an incorrect output result. I figured that I had just made a stupid error somewhere and set about finding it but 20 minutes of going over the code with a fine toothed comb revealed no errors. This got me good and confused.

    However, what really got me confused was that the exact same code that did this on my Mac worked perfectly on a Windows machine.

    After several hours of trying various things, scratching my head and saying "What the <insert curse-word of your choice>?!?" a lot (my teacher was not a lot of help. His advice was basically ..."I dunno about Macs. You're on your own."), I stumbled across a man page that seemed to say that fpurge could be substituted for fflush. I didn't really understand it but I did the swap and...BINGO!...working code on the Mac. This was great but I still had no idea why fflush worked on the Windows machine but not the Mac.

    I mentioned the fix to my teacher who told me that fflush was the standard proper C function and that fpurge was deprecated and non-standard. Now, please correct me if I am wrong but that seems to be the exact opposite of what the posts I have read here say, so, as you might expect, I am now very confused. Who do I believe?

    HELP?
    So, can anyone explain to me what is going on here? Why is it that the same source code can be run through the same complier and come up with 2 different outcomes? I apologize profusely if this is a really dumb question. I am aware that topics very similar to this have already been discussed on this forum (and I did read many of them) but I wasn't able to find anything that specifically related to this problem and, to be honest, the few discussions that did touch on this topic were a fair bit above my head so I didn't really follow them.

    I am hoping someone will be able to really spell it out in newbie-tastic terms for me.

    FUTURE CONCERNS
    Putting this specific problem aside for a moment, can anyone tell me if I am likely to come up against anything like this again? Are there many functions that work for windows but don't work at all (or don't work properly) on a Mac (and vice versa)? Is there some sort of list or database that details the differences between the two?

    My concern is that I'm going to encounter things like this regularly and it is going to severely hamper my progress in class which would be a pity because, apart from this little hiccup, I have really been enjoying learning about C and I'd hate to get left behind simply because I happen to use a different OS to the teacher.

    RELATED BUT SEPARATE QUESTION - NOT IMPORTANT BUT I AM INTERESTED
    Just to further complicate the issue, what about Linux (or UNIX) systems? Would the code for a Linux/UNIX machine be the same as the code for a Mac, the same as the code for a Windows box, or would it be a third, ever-so-slightly-different-to-both-the-others?

    As you can probably tell, this issue has pretty much thrown me for a loop and I'm now questioning my whole understanding (such as it is) of the way compilers interact with the OS and hardware and of C in general. I really feel like the rug has been pulled out from under me just when I thought I was getting a handle on how it all worked.

    Anyway, anyone who can point me in the right direction will certainly earn my undying gratitude.

    Once again, please accept my apologies if I've asked anything really silly and/or unforgivably basic and my thanks for taking the time out to help me, the poor dullard, out with what is bound to be for most of you, I'm sure, such an elementary concept.

    Cheers,
    Mark

  2. #2
    Devil's Advocate SlyMaelstrom's Avatar
    Join Date
    May 2004
    Location
    Out of scope
    Posts
    4,079
    Is that code from the teacher? If you're teacher is teaching you fflush(stdin), then you should have that teacher reported to the school board. It's terrible code.

    Anyway, you will have problems trying to code on a Mac OS when you have to compile and hand the assignments in on windows. That's why you should write you code as standard as possible.

    As for your other question... from what I know, code on Mac should be closer to *nix than Windows. They're both designed similar.
    Sent from my iPadŽ

  3. #3
    Registered User
    Join Date
    Feb 2006
    Posts
    17
    Wow, that is a long post
    Take a look at this and see if it gives you any ideas...
    Code:
    #include <stdio.h>
    
    int main(void)
    {
        int x;
        int y;
        int z;
        int c;
    
        printf("Enter a number for x: ");
        scanf("%d", &x);
        if ((c = getchar()) == '\n')
            printf("bingo!\n");
        
        printf("Enter a number for y: ");
        scanf("%d", &y);
        if ((c = getchar()) == '\n')
            printf("bingo, again!\n");
    
        printf("Enter a number for z: ");
        scanf("%d", &z);
        if ((c = getchar()) == '\n')
            printf("bingo one more time!\n");
    
        printf("The sum of x, y, and z is %d\n", x + y + z);
        return 0;
    }

  4. #4
    Registered User
    Join Date
    Feb 2006
    Location
    Sydney, Australia
    Posts
    40
    Hi,

    Yes, that is code from the teacher. Is it bad in some way? This class is the only exposure I have ever had to C so I don't know any different. If it is bad, I suspect that this may be part of the problem I am having.

    Also... Sorry, I think I may have given you the wrong impression...

    I don't have to compile and complete the assignments on a windows box, I can do it on the Mac, all the teacher wants is to see a printout of the source code and to see it running on a computer (which I can do on the Mac).

    The problem is that the code he is supplying in exercises (and the stuff he is teaching) is supposed to be standard ANSI C which is (or so I thought) platform independant. However, as evidenced by this problem I am having, perhaps it isn't. Is ANSI C supposed to be platform independant?

    According to the teacher, it is my code (or, more accurately, the way the Mac compiles and/or interprets it) that is non-compliant to the ANSI C standard, not his code, and he sites the fact that his code works with all the PC's to prove it.

    Who am I to disagree? I know squat about it but going by pure logical deduction (which, in the abscence of knowledge, is all I have to go on), the fact that his code works with the PC's but not with my Mac neither proves nor disproves that the Mac (or his code, for that matter) is to blame. There isn't enough info available to me to tell. I guess the only way to know would be to show a sample of his code to someone who knows what they are talking about and get their opinion.

    I have about a dozen example source files written by my teacher and I can post any or all of them here if anyone wants to see them. Just ask.

    So, I have no way of knowing if it's his code or my Mac. Maybe the Mac does work with ANSI C but the stuff he is teaching is some sort of weird thing that only works on Windows. Then again, maybe he's right and my Mac doesn't work with proper ANSI C code. As I said, I have no way of knowing, I just don't have enough knowledge on the subject. It's really confusing and frustrating. Kind of a chicken and egg problem.

    So anyway, as I said above, he told me that fflush was the proper function and that fpurge was depricated. My text book doesn't mention either function so, once again, my teacher has been my only source of info (until I did some digging this afternoon and found this forum). I still have no idea whether or not he is correct and I am only getting more and more confused the more I read. I could really use some clarification.

    Of course, as the only Mac user in the class, I am the only one with a problem, therefore the teacher doesn't seem to be too interested in helping me fix it. His fix is to forget the Mac and use windows box. I really don't want to do that, not least of all because I'd have to go out and buy one.

    So, anyway, if there is something wrong with that code could you tell me what it is? Is it just the fflush function or something else? Can you tell me if it's his code or my computer that isn't conforming to the relevent standards?

    I appreciate your reply but I could really use some more detail.

    Thanks,
    Mark

  5. #5
    Registered User
    Join Date
    Mar 2005
    Posts
    140
    fflush is a standard function, but is only defined to work on an ouput stream

    FAQ

    fflush MIGHT be defined to work with stdin (an input stream) depending on the platform and compiler, but by the standard it does not need to be defined. (It's not the fault of your compiler)
    Saying fflush(stdin) is ANSI C compliant is WRONG

    If it is defined there is nothing incorrect with using it, except that it makes your code non-portable as you have seen. Code that works on one machine does not work when compiled on another.


    More importantly you need to understand why you even need to flush the buffer at that point.
    Do you?
    If so you can use better methods to receive, validate, and process user input
    Last edited by spydoor; 02-27-2006 at 12:28 PM.

  6. #6
    Registered User
    Join Date
    Feb 2006
    Location
    Sydney, Australia
    Posts
    40
    Hi tcpl,

    Thanks for your reply. So quick!

    Yeah, it was kinda long, I had a bit of a hard time explaining my situation so I decided it was better to make sure I spelled it out. Took a while unfortunately.

    Yes, that code looks pretty familiar but I'm not sure what I am supposed to be looking at specifically.

    It looks just like the sort of code I've been learning over the past 4 weeks. I have no doubt that that program would compile fine on the Mac. The scanf and printf functions have always seemed to work, as have if statements.

    The first function I have come across that hasn't has been this fflush(stdin) statement. but your code doesn't seem to contain one of those.

    Sorry, am I being really thick? I don't understand what you are getting at.

    Sorry.

  7. #7
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    http://faq.cprogramming.com/cgi-bin/...&id=1043284351

    > ."I dunno about Macs. You're on your own."
    Your problem is down to your teacher teaching "works for me C" rather than standard C. fflush(stdin) does something apparently useful for most DOS programmers, but is utterly useless for anyone else - it may do something, nothing at all, or something completely hostile to your system.
    This is just the first example you have to deal with, god knows how many more horrors are in store. Best find a few online sources ( say here ) where you can verify everything your teacher says with people who have a clue.

    The whole flushing issue goes away if you use fgets() to read a line of input, then sscanf() (or any other string conversion function) to convert that input into a form you want.

  8. #8
    Registered User
    Join Date
    Feb 2006
    Location
    Sydney, Australia
    Posts
    40
    Quote Originally Posted by spydoor
    fflush is a standard function, but is only defined to work on an ouput stream

    <snip>

    fflush MIGHT be defined to work with stdin (an input stream) depending on the platform and compiler, but by the standard it does not need to be defined. (It's not the fault of your compiler)
    Saying fflush(stdin) is ANSI C compliant is WRONG

    If it is defined there is nothing incorrect with using it, except that it makes your code non-portable as you have seen. Code that works on one machine does not work when compiled on another.
    Ah, OK, some clarification. w00t! Thank you so much, I at least now have a starting point.

    More importantly you need to understand why you even need to flush the buffer at that point.
    Do you?
    If so you can use better methods to receive, validate, and process user input
    Actually, no, I am sorry to say that I don't. As you may have picked up, my teacher is not the most approachable I've ever had and I have not been able to get him to explain it to me. I had intednded to just research it myself either from the text book or by trying my luck with google. I figured it's be easier but I haven't gotten around to it yet since I've been preoccupied with this other problem.

    You have no idea how much of a relief it is to finally have a concrete starting point though. Thanks.

  9. #9
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Instead of:
    Code:
    scanf("%c", &arithOp);
    You might try this:
    Code:
    scanf(" %c", &arithOp);
    Notice the extra space in front of the '%'. When reading in the character here, your scanf call is getting a newline character that is left in the input buffer from the previous call to scanf.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  10. #10
    Registered User
    Join Date
    Feb 2006
    Location
    Sydney, Australia
    Posts
    40
    Quote Originally Posted by Salem
    http://faq.cprogramming.com/cgi-bin/...&id=1043284351

    > ."I dunno about Macs. You're on your own."
    Your problem is down to your teacher teaching "works for me C" rather than standard C. fflush(stdin) does something apparently useful for most DOS programmers, but is utterly useless for anyone else - it may do something, nothing at all, or something completely hostile to your system.
    This is just the first example you have to deal with, god knows how many more horrors are in store. Best find a few online sources ( say here ) where you can verify everything your teacher says with people who have a clue.

    The whole flushing issue goes away if you use fgets() to read a line of input, then sscanf() (or any other string conversion function) to convert that input into a form you want.
    Wow! Thanks so much for all this help people. I was really stressing about this and I am finally starting to feel like there is a light at the end of the tunnel (maybe I can even get some sleep after all ).

    I'm so glad that it seems that it is probably not my (or my computer's) fault.

    I am not familiar with the fgets() function but I will certainly look into it as soon as I get a chance. We have only learnt scanf, printf, fflush (sort of) and if-else statements so far.

    I think I have a lot of extra-curricular studying to do. I guess my main problem is that my teacher says he is teaching ANSI C but isn't really. I suppose I'll just have to learn for myself.

    Once again, thank you all for your extremely prompt replies.

  11. #11
    Registered User
    Join Date
    Feb 2006
    Location
    Sydney, Australia
    Posts
    40
    Quote Originally Posted by hk_mp5kpdw
    Instead of:
    Code:
    scanf("%c", &arithOp);
    You might try this:
    Code:
    scanf(" %c", &arithOp);
    Notice the extra space in front of the '%'. When reading in the character here, your scanf call is getting a newline character that is left in the input buffer from the previous call to scanf.
    Yes, I read about this happening during my frantic research this afternoon before finding this forum.

    However, isn't that what the fflush is there for? To clear the input buffer so that the newline char doesn't get picked up by the scanf function (I am by no means sure but it seems to make sense)? Or is that your point? The fflush function isn't working because it is not ANSI C so my compiler doesn't recognise it and that is why the program is rolling straight through it?

    Sorry, I know I must sound as thick as a whale omelette. I'm really having a hard time getting to grips with this because of all the misinformation I've been dealing with.

    So what exactly does the extra space in front of the % do? I mean, I know the end result (ie. It stops the newline from being picked up by scanf) but how/why does the space do that?

    I'm going to go to bed now (I'm in Sydney, Australia and it's nearly 6am) so I'll be gone a few hours but I'll check back later today.

    Once again, thank you all so much for your prompt replies. I can't believe how quickly I got advice. Good advice at that!

    Cheers,
    Mark

  12. #12
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by tvsinesperanto
    So what exactly does the extra space in front of the % do? I mean, I know the end result (ie. It stops the newline from being picked up by scanf) but how/why does the space do that?
    http://groups.google.com/group/comp....ae142d523723d7
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > I guess my main problem is that my teacher says he is teaching ANSI C but isn't really.
    Well if he comes out with "void main" and using gets() to read input, then you'll know for sure that you have a bad'un.

    These 3 things are the unholy trinity of the truly clueless.

  14. #14
    Registered User
    Join Date
    Feb 2006
    Location
    Sydney, Australia
    Posts
    40
    Quote Originally Posted by Dave_Sinkula
    Hello again,

    My most sincere thanks to all of you who offered me help on this problem. Adding the space before the %c did the trick nicely, as did replacing fflush with fpurge. I decided to go for the extra space option though since, for some reason, the teacher seems to use the fflush function in most of the relevant examples and exercises he sets and I'd prefer to stay as close as possible to his examples until I feel confident in my own understanding.

    Anyway, the immediate emergency has been averted and I can now continue along with the rest of the class.

    However, I am embarrassed to say that I still don't quite understand exactly what the space is doing to fix the problem. Can anyone explain it to me in dummy talk? The explanations given in the link above and the FAQ link (thank you salem, spydoor and Dave_Sinkula) were somewhat helpful but are still a little over my head (I'm really sorry. I hate being a clueless newbie probably more than you hate being asked stupid newbie questions).

    I understand that the problem is caused by something that the previous scanf function does (something to do with a left over newline perhaps?) and that it has something to do with whitespace, but I'm afraid I just don't have enough background knowledge yet to fully understand it.

    If it's not really possible to dumb the explanation down any further then I will reluctantly just have to take it on faith that this is the way to get around the problem until I learn more about it. However, I hate having to rely on a set of mindless "rules" and would much rather understand the underlying principles, so if anyone can simplify it further for me, I'd appreciate it.

    Once again, many thanks.

    Cheers.

  15. #15
    ex-DECcie
    Join Date
    Dec 2005
    Posts
    125
    Simply put, "a whitespace character in the control string causes whitespace characters to be read and discarded". That's from page 378 of "A C Reference Manual", fifth edition, by Harbison and Steele. (Very good book to have).

    Regarding your teacher, I'll offer a "Personal Opinion Fueled by Personal Bias" here...

    Teachers are (for the most part in my experience) just that. They teach. In my experience, not that many of them have ever butted heads against code that needs to run on multiple platforms successfully, needing to be done on time, within budget etc etc. You learn a lot from living in that everyday programming environment, and teachers don't have that experience level.

    That is not to say that every teacher is like that. I've had some excellent folks teaching courses that I've gone to (usually training from work). In that instance, they've worked in the trenches and moved to a trainer position -- they still have that experience behind them.

    Please visit here often, and ask your questions. You will usually get a good, solid answer. We were all noobs at one point or another, and I can't speak for everyone else, but I had good mentors along the way, so I feel I should return the favor.

    Good luck!
    Mr. Blonde: You ever listen to K-Billy's "Super Sounds of the Seventies" weekend? It's my personal favorite.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A place to start - mac or pc?
    By GCat in forum C++ Programming
    Replies: 12
    Last Post: 11-19-2004, 12:21 PM
  2. Mac programming?
    By Luigi in forum A Brief History of Cprogramming.com
    Replies: 17
    Last Post: 02-07-2003, 09:37 PM