Solved

Very basic but not works

Posted on 2004-09-15
16
611 Views
Last Modified: 2008-02-26
Hi,

I must missed something very basic in following code! It just not allowed me to enter 'y' or 'n':

#include <stdio.h>
void main()
{float f; int con='y';
while(con=='y')
{
scanf("%f",&f);
printf("%f   Continue(y/n)?",f); con=getchar();
}
}
0
Comment
Question by:daveask
  • 4
  • 3
  • 3
  • +5
16 Comments
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 12070810
Your code appears to be good, but you have to consider this:
getchar doesn't expect an enter to take action.
You have to consider uppercase/lowercase in your while statement:

while(con=='y' || con=='Y')

0
 

Author Comment

by:daveask
ID: 12070857
Thank you. However, you didn't answer my question.
The problem is the loop in my code just stopped before I enter 'y' or 'n'.
0
 
LVL 1

Accepted Solution

by:
JoalT earned 20 total points
ID: 12070859
Hi daveask,

scanf() is actually a somewhat tricky function to use, as you have found.
The problem is that you typed in a number and pressed enter. scanf()
read in the number, but not the newline generated by pressing enter.
So it is still sitting there waiting to be read. Then you call getchar(), which
obligingly reads in the newline. Thus, you don't get the chance to answer
the "Continue(y/n)?" question.

Probably the easiest solution is to use fgets() to read the entire line of
input instead. Then use sscanf() to extract the number out of that line.

Bear in mind that getchar() will suffer a similar problem here: it will read the 'y'
character (say), but the newline will not be read. So I advise a similar
approach; use fgets() to read a line of input and then check if the first
character is 'y' (maybe after converting it to lower case so that entering
'Y' also works).
0
 
LVL 55

Assisted Solution

by:Jaime Olivares
Jaime Olivares earned 20 total points
ID: 12070914
I think you need a bit of order and some changes in your code:

#include <stdio.h>
#include <conio.h>
main()
{
    float f;
    int con='y';
    while(con=='y' || con=='Y')
    {
    printf("\r\nEnter number: ");
    scanf("%f",&f);
    printf("\r\n%f   \r\nContinue(y/n)? ",f);
    fflush(stdin);
    con=getch();
    }
}
0
 
LVL 11

Assisted Solution

by:avizit
avizit earned 20 total points
ID: 12071452
#include <stdio.h>
void main(){
  float f;
  char con = 'y';
  while( con == 'y') {
    printf("enter a number\n");
    scanf("%f",&f);
    printf("%f   Continue(y/n)?",f);
    scanf(" %c",&con);
    /* con=getchar(); */
  }
}

====

note the space in front of %c in    scanf(" %c",&con);

and also check my last response in http://experts-exchange.com/Programming/Programming_Languages/C/Q_21129807.html

0
 
LVL 6

Expert Comment

by:msjammu
ID: 12071998
#include <stdio.h>
void main()
{
        float f; int con='y';
        while(con=='y')
        {
               scanf("%f",&f);
               printf("%f   Continue(y/n)? ",f);
               fflush(stdin); // flushes the input stream
               con=getchar(); //con = getch() or getche() will also work
        }
}

fflush(stdin); empty any characters lying in input stream
0
 
LVL 11

Expert Comment

by:avizit
ID: 12072035
1) msjammu ,  jaime_olivares has already suggested  fflush(stdin)

2) have you tried your solution if it works ?

fflush is defined only for output streams ...

from http://www.eskimo.com/~scs/C-faq/q12.26.html


How can I flush pending input so that a user's typeahead isn't read at the next prompt? Will fflush(stdin) work?

fflush is defined only for output streams. Since its definition of ``flush'' is to complete the writing of buffered characters (not to discard them), discarding unread input would not be an analogous meaning for fflush on input streams.

There is no standard way to discard unread characters from a stdio input stream, nor would such a way be sufficient unread characters can also accumulate in other, OS-level input buffers.
0
 

Author Comment

by:daveask
ID: 12080176
Hi experts,

Why stopped discuss?
I tested buth
    fflush(stdin);   con=getchar();
and
    scanf(" %c",&con);
work in both MS visual C++ 6.0 and TC201.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 6

Expert Comment

by:msjammu
ID: 12081358
>>1) msjammu ,  jaime_olivares has already suggested  fflush(stdin)

I am sorry I didn't saw this comments..
0
 
LVL 5

Expert Comment

by:info_expert
ID: 12084608
Hi,

I tested your code. thers no error in your code.

You probabely had used capslock causing the program to enter Y instead of y.

Regards.
0
 
LVL 55

Expert Comment

by:Jaime Olivares
ID: 12084700
Maybe you have been confused with this situation (in your original code):

After printing result and aswering 'y', scanf becomes active, but you don't notice because you didn't print a message before scanf, and maybe you believe that getchar continues asking for a key, but it is really the scanf asking for the next number.
That's why I have inserted some printf's with newlines in my proposed code.
0
 
LVL 9

Expert Comment

by:jhshukla
ID: 12085009
scanf will scan till the end of the line and leave the '\n' in the stream.
then you use getchar which extracts the newline character and stores it to con. when you test con for 'y' it fails and you exit the loop!
insert another while loop after getchar() like this:
printf(...)
con=getchar();
while(isspace(con) || con=='\n'){ con = getchar(); }

this will not do anything unless the user inputs a non printable char. it also makes your program slightly flexible by allowing spaces after the floating point number.

jaydutt
0
 
LVL 6

Expert Comment

by:msjammu
ID: 12090549
avizit:
2) have you tried your solution if it works ?
fflush is defined only for output streams ...

May I hope you try fflush() yourself and clear your doubts first, Plz go through that link.
fflush is used for any type of stream.

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_crt_fflush.asp

Take Care,
0
 
LVL 1

Assisted Solution

by:decentswati
decentswati earned 30 total points
ID: 12099219
hi daveask,
 as joaIt explains, it is correct.I just give u the simplest approach ofcourse an simplest one.If u want these code as it is.just write an extra getchar() in ur code so that the "enter" value transfer to the new getchar() and now ur program is ready to accept ur answer.

in loop
scanf...;
printf....;
getchar();
con=getchar();

now it will sure work.

happy coding...
0
 
LVL 11

Expert Comment

by:avizit
ID: 12151266
msjammu:

That is MSDN extension and not ANSI C , hence not portable.

from
http://www.infosys.utas.edu.au/info/documentation/C/CStdLib.html#fflush
http://www.tcnj.edu/~cs/doc/CStdLib.html

int fflush(FILE* stream);
    Flushes stream stream and returns zero on success or EOF on error. "Effect undefined for input stream." fflush(NULL) flushes all output streams.


and from "The Open Group Base Specifications Issue 6"  which is a IEEE standard

hence the standard says the effect is undefined and is implementation dependent and hence we cant rely on fflush(stdin) to flush the stdin all the time .. while it may work for systems employing MSDN , it will result in very unportable code and difficult to trace bug.

ps: sorry of I sounded rude the first time , that was not my intention
0
 
LVL 11

Expert Comment

by:avizit
ID: 12151281
apropos to the above

http://www.mega-nerd.com/erikd/BOOK/faq.html#Q5

 Q 5 : In chapter 13, listing 6, fflush (stdin) doesn't work like its supposed to. Why is that?

This is a bug :-).

The problem with the existing code occurs when a program reads user input, then does some time consuming processing (say more than a couple of seconds) before reading more user input. In this situation, the user might type some more on the keyboard while the program is processing and these characters will be buffered by the operating system and read on the next read call. The idea of the existing code was to use fflush (stdin) to flush all the stored characters from the input buffer.

As Benjamin Black pointed out, the C Programming FAQ states that the behaviour of fflush () is defined only for output streams. To make matters worse there is no standard ANSI/ISO C way of doing this. Fortunately there is a POSIX solution.

The POSIX solution is to use the low-level unbuffered input functions or GNU/Linux specific higher level function which in turn use the lower level ones. There are examples of both here.
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
Windows programmers of the C/C++ variety, how many of you realise that since Window 9x Microsoft has been lying to you about what constitutes Unicode (http://en.wikipedia.org/wiki/Unicode)? They will have you believe that Unicode requires you to use…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to use strings and some functions related to them in the C programming language.

758 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now