468,760 Members | 1,899 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 468,760 developers. It's quick & easy.

output problem

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);

/* prompt the user to enter the artist name */
printf("Please enter the artist name ... \n");
printf("artist? ");
scanf("%s", artist);
/* 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), also issue was the same
when i tried fflush(stdin) after scanf() statements.That problem dose
not exist when using %s instead of [^\n]
but i have to enter one word (the first name only)
any opinion?

thanks in advanced

Apr 19 '07 #1
11 1676
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
Apr 19 '07 #2
On Apr 19, 8:58 pm, Eric Sosman <Eric.Sos...@sun.comwrote:
aljaberwrote 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.

--
Eric.Sos...@sun.com
Mr, Eric.
many thanks to you, and it is not enough.
thanks again for the time you gave to replay.

Apr 19 '07 #3
In article <1177009117.354179@news1nwk>
Eric Sosman <Er*********@Sun.COMwrote:
>What does [scanf's] "%[^\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[] ...
Small but important correction: when the directive fails, as
in this case, scanf() terminates, leaving artist[] unchanged.

The return value from scanf() tells you how many assignments
were succesfully completed. For instance:

n = scanf("%d%d%d", &e, &f, &g);

attempts to read three "int"s (%d) and store them into e, f, and
g respectively; but if only one "int" is available before scanf()
runs into trouble, only e will receive a value: f and g will remain
unchanged. The scanf() call will return 1, setting n to 1.

If scanf() returns 0, it must have run into a matching failure
before doing any assignments. If scanf() returns EOF, it ran out
of input (due to either EOF *or* error) before doing any assignments.

Since scanf() cannot, in general, tell you how far it got (there
are some exceptions using "%n" directives but they are limited),
the scanf() function should almost never be used. Really, seriously:
beginners should never call scanf(). Using sscanf() is OK, but
using scanf() directly is not.
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.
(This, however, runs into other problems.)
... but all these (and more) are really just work-
arounds. scanf() is not a good tool for interactive
input ...
Indeed.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Apr 20 '07 #4
Chris Torek wrote:
In article <1177009117.354179@news1nwk>
Eric Sosman <Er*********@Sun.COMwrote:
>What does [scanf's] "%[^\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[] ...

Small but important correction: when the directive fails, as
in this case, scanf() terminates, leaving artist[] unchanged.
Ah! Good catch; thank you. "%[...]" succeeds only if it
can match a non-empty sequence, so when '\n' is the next input
character "%[^\n]" fails and does nothing instead of matching
a zero-length string and doing something with it. My mistake.

--
Eric Sosman
es*****@acm-dot-org.invalid
Apr 20 '07 #5
On Thu, 19 Apr 2007 22:19:57 -0400, Eric Sosman
<es*****@acm-dot-org.invalidwrote:
>Chris Torek wrote:
>In article <1177009117.354179@news1nwk>
Eric Sosman <Er*********@Sun.COMwrote:
>>What does [scanf's] "%[^\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[] ...

Small but important correction: when the directive fails, as
in this case, scanf() terminates, leaving artist[] unchanged.

Ah! Good catch; thank you. "%[...]" succeeds only if it
can match a non-empty sequence, so when '\n' is the next input
character "%[^\n]" fails and does nothing instead of matching
a zero-length string and doing something with it. My mistake.
per me sembrate due secchioni!
Apr 21 '07 #6
Chris Torek wrote:
Since scanf() cannot, in general, tell you how far it got (there
are some exceptions using "%n" directives but they are limited),
the scanf() function should almost never be used. Really, seriously:
beginners should never call scanf().
If they never call scanf(), they never acquire experience in using it.
I'd advise: Use scanf() whenever you like, and learn from your errors.
That way, someday they'll no longer be beginners.
--
DPS
Apr 26 '07 #7
Dietmar Schindler <DS***@Arcor.Dewrites:
Chris Torek wrote:
>Since scanf() cannot, in general, tell you how far it got (there
are some exceptions using "%n" directives but they are limited),
the scanf() function should almost never be used. Really, seriously:
beginners should never call scanf().

If they never call scanf(), they never acquire experience in using it.
And that's a problem because ...?
I'd advise: Use scanf() whenever you like, and learn from your errors.
That way, someday they'll no longer be beginners.
Perhaps. There's certainly nothing wrong with learning how scanf()
works. But once you've learned how it works, the best conclusion to
draw from the experience is probably just to avoid it. (sscanf() is
another matter.)

Note also that scanf(), sscanf(), and fscanf() all invoke undefined
behavior if they attempt to read a numeric value and the input
specifies a value that can't be represented in the specified type.
None of them provides a way to anticipate or handle numeric overflow.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Apr 26 '07 #8
On Thu, 26 Apr 2007 15:41:34 +0200, in comp.lang.c , Dietmar Schindler
<DS***@Arcor.Dewrote:
>I'd advise: Use scanf() whenever you like, and learn from your errors.
Hm, the "give the kids a gun to play with, whats the worst that could
happen?" approach. Cool.
>That way, someday they'll no longer be beginners.
Or, quite possibly, employed... :-(

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Apr 26 '07 #9
Chris Torek wrote:
>
>Since scanf() cannot, in general, tell you how far it got (there
are some exceptions using "%n" directives but they are limited),
the scanf() function should almost never be used. Really,
seriously: beginners should never call scanf().
Piggybacking. Why do you say that? It returns the number of
conversions made, and a failed conversion prevents advancing to the
next.

--
<http://www.cs.auckland.ac.nz/~pgut001/pubs/vista_cost.txt>
<http://www.securityfocus.com/columnists/423>
<http://www.aaxnet.com/editor/edit043.html>
<http://kadaitcha.cx/vista/dogsbreakfast/index.html>
cbfalconer at maineline dot net

--
Posted via a free Usenet account from http://www.teranews.com

Apr 27 '07 #10
>Chris Torek wrote:
>>Since scanf() cannot, in general, tell you how far it got (there
are some exceptions using "%n" directives but they are limited),
the scanf() function should almost never be used. Really,
seriously: beginners should never call scanf().
In article <46***************@yahoo.com>,
CBFalconer <cb********@maineline.netwrote:
>Piggybacking. Why do you say that? It returns the number of
conversions made, and a failed conversion prevents advancing to the
next.
The problem is that you give up somewhere from "a bit" to "all"
control over the input stream during the "getting of input". For
instance, beginners almost invariably seem to think that "\n"
matches exactly one newline, when in fact it gives up control of
input until a non-white-space character is entered. Worse, since
most directives skip leading whitespace (including newlines), but
also leave trailing whitespace (particularly newlines) behind, the
stream almost always winds up in an "unexpected" (by the beginner
at least) state.

The solution is to read whole lines (with fgets() or ggets() or
something like those), then -- if desired, or in order to learn
about scanf() -- apply sscanf() to the single-line input, and/or
to inputs made by concatenating several lines.

Once the behavior of sscanf() on "pre-controlled" input is mastered,
the (no longer beginner) programmer can, if desired, move on to
attempting to use scanf() directly.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Apr 27 '07 #11
Keith Thompson wrote:
>
Dietmar Schindler <DS***@Arcor.Dewrites:
...
If they never call scanf(), they never acquire experience in using it.

And that's a problem because ...?
Well, it's a problem only for someone who is not comfortable with being
inexperienced.
...
Note also that scanf(), sscanf(), and fscanf() all invoke undefined
behavior if they attempt to read a numeric value and the input
specifies a value that can't be represented in the specified type.
None of them provides a way to anticipate or handle numeric overflow.
That's true, but they provide a way to avoid it; for example, the
conversion specification %4d shall do.
--
DPS
Apr 27 '07 #12

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Lisa | last post: by
5 posts views Thread by Tom Lam lemontea | last post: by
6 posts views Thread by Alec MacLean | last post: by
1 post views Thread by CARIGAR | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.