473,394 Members | 2,020 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,394 software developers and data experts.

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 1909
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 (40°39.22'N, 111°50.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 (40°39.22'N, 111°50.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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: Jay Chan | last post by:
I am trying to use a command line program to run a stored procedure that generates output in a comma-delimitted format. Somehow, ISQL or OSQL always wrap the lines at 256 characters. I believe this...
1
by: Lisa | last post by:
I need to apply the HTML formatting tags and the French accented characters in a XML document. The XML is generated from a database that has HTML tags and French accented characters in the records....
11
by: Etienne Charland | last post by:
Hi, I have a solution containing 6 C# projects; 1 WinForms project and 5 class libraries. I didn't have any problems until recently. I added a new project containing reports. I am using...
3
by: Dalan | last post by:
Perhaps someone has experienced this problem. I developed an Access 97 Runtime database on a Windows 98 SE machine. I have three reports that can be optionally copied to a floppy disk or hard drive...
5
by: Tom Lam lemontea | last post by:
Hi all, This is my very first post here, I've seriously tried some programming on C, and shown below is my very first program(So you can expect it to be very messy) that I wrote after I've learned...
4
by: Mountain Bikn' Guy | last post by:
I am having serious problems with the following IDE bug: Could not write to output file 'x.dll' -- 'The process cannot access the file because it is being used by another process. ' and BUG:...
5
by: Brad | last post by:
I created a base page class which sets a response filter and the filter injects additional html into the response output stream. The filter works fine and everything works as expected except for...
6
by: Alec MacLean | last post by:
Hi, I've created a small application for our company extranet (staff bulletins) that outputs a list of links to PDF's that are stored in a SQL table. The user clicks a link and the PDF is...
4
by: Jon | last post by:
Hi, I used XslCompiledTransform with the following Xsl file. The <xsl:text disable-output-escaping="yes"does not work when using XslCompiledTransform to do the trnasform (namely the output...
8
by: Alec MacLean | last post by:
Hi, I'm using the DAAB Ent Lib (Jan 2006) for .NET 2.0, with VS 2005 Pro. My project is a Web app project (using the WAP add in). Background: I'm creating a survey system for our company, for...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.