aljaber wrote On 04/19/07 13:19,:
hi,
i am facing a problem with my program output
here is the program
/*********************************************\
* CD Database *
* *
\*********************************************/
#include <stdio.h>
main()
{
char title[61]; /* CD title */
char artist[61]; /* Artist Name */
printf(" Welcome to the CD database ... \n");
/* prompt the user to enter the CD title */
printf("Please enter the title of the CD ... \n");
printf("Title? ");
scanf("%[^\n]", title);
This line reads characters from stdin and stores
them in title[], stopping when it reads a '\n'. What
you've missed is that the '\n' is not consumed: it is
still "pending" on stdin, waiting to be read by another
input function.
(By the way, you will have lots of trouble if the
user enters a title longer than 60 characters ...)
/* prompt the user to enter the artist name */
printf("Please enter the artist name ... \n");
printf("artist? ");
scanf("%s", artist);
The "%s" specifier works a little differently from
"%[...]". It starts by reading and discarding white
space characters from the input -- the first one it
reads and discards is the '\n' that stopped the first
scanf(). When it finds a non-white character, it
stores it in artist[] and continues reading and storing
characters until it finds another white space character,
when it stops. Just as with the first scanf(), the
character that stops the input remains "pending" on
stdin.
So: If the user enters "Steppenwolf\n", this call
will discard the left-over '\n', store "Steppenwolf"
in artist[] (as before, there would be trouble if the
user entered a Really Long artist name), and will leave
the final '\n' pending on stdin, ready to be consumed
by the next input operation.
But if the user enters "Wiener Philharmoniker\n",
this call will discard the left-over '\n', store "Wiener"
in artist[] and then stop because of the ' ' character.
The " Philharmoniker\n" part will remain un-read. This
was (I guess) the problem you were trying to fix.
>
/* CD details output */
printf("The CD details you entered are : \n");
printf(" ================================\n");
printf("Title : %s\n", title);
printf("Artist: %s\n", artist);
printf(" ================================\n");
printf("Thanks for using our program ...\n");
}
when i try to enter the last name of the artist after the first name
separated with space,
with using %[^\n] instead of %s in line 27 ,when i run the program it
just prompt me for the (the title) first scanf() only
and the program exit without prompting me for the second scanf()
(artist name),
What does "%[^\n]" do? It reads and stores characters
until it finds a '\n', which it does not store and does
not consume. What is the first character it reads? The
'\n' that stopped the first scanf(). What does that '\n'
do to this "%[^\n]"? It causes it to stop reading, to
store a zero-length string in artist[], and to leave the
'\n' still sitting on stdin, waiting to be read.
also issue was the same
when i tried fflush(stdin) after scanf() statements.
fflush() only works on output streams (or on update
streams whose most recent operation was not input). When
you try to use it on an input stream like stdin, you get
undefined behavior. Don't Do That.
That problem dose
not exist when using %s instead of [^\n]
but i have to enter one word (the first name only)
any opinion?
You can use "%[^\n]" for both lines of input, but
you need to swallow the pending '\n'. One way to do it
is to use " %[^\n]", because a white space character in
the format string matches and consumes any arbitrary
amount of white space from the input. So if there's a
'\n' pending on stdin, the leading ' ' in the format
string will swallow it and then the "%[^\n]" will start
on the data from the next line. Note that the leading
' ' will swallow *all* white space until something non-
white appears, so if the user enters " Blank \n"
the new format will store only "Blank " in artist[].
Do *not* use "%[^\n]\n" in an attempt to get rid
of the trailing '\n'. Once again: any white space in
the format will swallow all the input white space it can
find, so the final '\n' in the format will keep reading
and reading and reading until the user enters something
non-white. Result: The user will need to enter the artist
name *before* the program prompts for it!
You could also use "%[^\n]%*c" to swallow the '\n'
and discard it: The "%*c" directive reads one character,
and the '*' says not to bother storing it anywhere.
... but all these (and more) are really just work-
arounds. scanf() is not a good tool for interactive
input, in part because it doesn't "understand" line
boundaries: Everything on stdin is just one big long
undifferentiated stream of input as far as scanf() is
concerned. It is usually much more satsifactory to read
an entire line of input into a char array with fgets()
(*not* with gets()!), and then to extract information
from the array with sscanf() -- two s's -- or with other
string-handling functions.
--
Er*********@sun.com