467,084 Members | 1,190 Online
Bytes | Developer Community
Ask Question

Home New Posts Topics Members FAQ

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

do {...} while () ;

I don't understand the reason cos this cycle:

do {
printf ("\nCome devono essere posizionati gli elementi?\n") ;
printf ("* premere E, nel caso di posizionamento sul piano
E\n") ;
printf ("(ricezione onde orizzontali);\n") ;
printf ("* premere H, nel caso di posizionamento sul piano
H\n") ;
printf ("(ricezione onde verticali).\n") ;
scanf ("%c", &scelta_piano) ;
} while ((scelta_piano != 'H') && (scelta_piano != 'h') &&
(scelta_piano != 'E') && (scelta_piano != 'e')) ;

write its content two time. So the output is:

Come devono essere posizionati gli elementi?
* premere E, nel caso di posizionamento sul piano E
(ricezione onde orizzontali);
* premere H, nel caso di posizionamento sul piano H
(ricezione onde verticali).

Come devono essere posizionati gli elementi?
* premere E, nel caso di posizionamento sul piano E
(ricezione onde orizzontali);
* premere H, nel caso di posizionamento sul piano H
(ricezione onde verticali).

I hope someone can help me.
Bye bye Aleramo.

Feb 25 '06 #1
  • viewed: 1458
Share:
14 Replies
Aleramo wrote:
I don't understand the reason cos this cycle:

do {
printf ("\nCome devono essere posizionati gli elementi?\n") ;
printf ("* premere E, nel caso di posizionamento sul piano
E\n") ;
printf ("(ricezione onde orizzontali);\n") ;
printf ("* premere H, nel caso di posizionamento sul piano
H\n") ;
printf ("(ricezione onde verticali).\n") ;
scanf ("%c", &scelta_piano) ;
} while ((scelta_piano != 'H') && (scelta_piano != 'h') &&
(scelta_piano != 'E') && (scelta_piano != 'e')) ;

write its content two time. [...]


Probably because the first character read by scanf()
was not H, h, E, or e. You could check this by adding
an extra printf() right after the scanf(), for debugging
purposes:

printf ("Input is '%c' (code %d or 0x%X)\n",
scelta_piano, scelta_piano, scelta_piano);

Where did that phantom character come from? It was
probably from some earlier input that a previous scanf()
did not consume. For example, if your program executed

int numero;
...
printf ("Enter an integer\n");
scanf ("%d", &numero);

.... and you responded by pressing 4 and 2 and ENTER, the
first scanf() would convert the 4 and 2 and store the value
42 in numero. However, the line also contained a newline
character '\n', which the first scanf() would not swallow.
When the second scanf() executes, it finds the newline and
stores it in scelta_piano. Your program sees that '\n' is
not one of H,h,E,e, so it repeats. The second time through
the loop, scanf() finds the character you intended, stores
it in scelta_piano, and your program accepts it.

scanf() is not a very good function for interactive input,
because it treats the input as one long stream of characters.
Usually, interactive input should be "synchronized" by some
mechanism like pressing ENTER, and this means that it is more
natural to think of interactive input as a sequence of complete
lines. One way to deal with this problem is to use fgets()
to read a complete line into a character array, and then use
sscanf() -- two s'es -- to "read" from the character array.

--
Eric Sosman
es*****@acm-dot-org.invalid
Feb 25 '06 #2
Aleramo wrote:
I don't understand the reason cos this cycle:

do {
printf ("\nCome devono essere posizionati gli elementi?\n") ;
printf ("* premere E, nel caso di posizionamento sul piano
E\n") ;
printf ("(ricezione onde orizzontali);\n") ;
printf ("* premere H, nel caso di posizionamento sul piano
H\n") ;
printf ("(ricezione onde verticali).\n") ;
scanf ("%c", &scelta_piano) ;
} while ((scelta_piano != 'H') && (scelta_piano != 'h') &&
(scelta_piano != 'E') && (scelta_piano != 'e')) ;

write its content two time. So the output is:


<snip>

In future, please provide a *complete* compilable example that
demonstrates your problem and also tell us what input you are using. The
bug could be anywhere in the 250000 lines of code you have not posted.
However, I'm in a good mood and I'll guess that you have this problem
somewhere in the code you did not post
http://c-faq.com/stdio/scanfinterlace.html

In general I would recommend against using scanf. Use fgets (not, *ever*
the more appealing looking gets) and then pass the line you have read
using the tool of choice, be that sscanf, strtol, a hand written passer
or whatever.
--
Flash Gordon, living in interesting times.
Web site - http://home.flash-gordon.me.uk/
comp.lang.c posting guidelines and intro:
http://clc-wiki.net/wiki/Intro_to_clc
Feb 25 '06 #3
Aleramo wrote:

I don't understand the reason cos this cycle:

do {
printf ("\nCome devono essere posizionati gli elementi?\n") ;
printf ("* premere E, nel caso di posizionamento sul piano
E\n") ;
printf ("(ricezione onde orizzontali);\n") ;
printf ("* premere H, nel caso di posizionamento sul piano
H\n") ;
printf ("(ricezione onde verticali).\n") ;
scanf ("%c", &scelta_piano) ;
} while ((scelta_piano != 'H') && (scelta_piano != 'h') &&
(scelta_piano != 'E') && (scelta_piano != 'e')) ;

write its content two time. So the output is:


I suggest you think about it differently. I believe you want to
present a prompt, and get one of a subset of possible response
characters. So isolate this operation in a function.

int promptandgetresponse(const char *prompt,
const char *acceptable);

Note the return of an int, so that an EOF can be detected. The
assumption is being made that stdout is used for prompting, and
stdin for input. You could add parameters to control this, if
desired. So the first step is to present the prompt:

do {
if (prompt) {
printf("%s", prompt); fflush(stdout);
}
/* Now get a reply */
} while ( /* reply is not satisfactory */ );

Note the fflush, which allows the prompt to not end with a \n. The
test on prompt allows you to avoid prompting entirely, by supplying
NULL.

Looking at this you may see a possible problem. How is the user to
know why his response is not acceptable? So you may want to modify
the system to give feedback on this later. This is left as an
exercise.

Now, how do we get a reply? There is no need to complicate things
with the highly unruly scanf if we keep a couple of useful
auxiliary routines around:

int skipblanks(void) {
int ch;
while (' ' == (ch = getchar())) continue;
return ch;
}

which will gobble up leading blanks. We can also gobble up all
unused line portions with:
+
int flushln(void) {
int ch;
while (('\n' != (ch = getchar())) && (EOF != ch)) continue;
return ch;
}

Notice that both routines will exit, and return EOF, if an EOF is
encountered. These routines are so useful that you should always
have them available for interactive use. They are better
generalized to access arbitrary files, supplied as a parameter.

Now lets embellish the promptandgetresponse routine to use these.

int promptandgetresponse(const char *prompt,
const char *acceptable)
{
int ch;

do {
if (prompt) {
printf("%s", prompt); fflush(stdout);
}
/* Now get a reply */
ch = skipblanks(); /* get first non-blank char */
if ('\n' != ch) flushln(); /* set up to try again */
} while ( /* reply is not satisfactory */ );
return ch;
}

This hasn't resolved "reply is not satisfactory" yet, and has some
other minor difficulties. You should try the condition:

strchr(acceptable, ch)

to replace that comment. This will require #include <strings.h>.

Things to think about: What if the user enters only an empty
line? You could make this select a default, such as the first
character in acceptable. What if an EOF is encountered while
skipping blanks? while executing flushln? You can resolve most of
these by insisting that responses be properly terminated with '\n',
i.e. an <enter> on most machines. Otherwise you will return an EOF
and not try to preserve data from an invalid entry. After all,
once EOF has been signalled you can't do anything more.

Once you get this running cleanly, you will have solved many of
your interactive problems for the future. Note that the routine(s)
need not be long and complex, rather they should be short and you
should be able to see flaws easily on inspection.

BTW, notice that the code I am proposing is not confused by
language difficulties. What the prompt is, and its language, have
no effect whatsoever. Similarly the translation of single char.
responses.

The above code is untested. So beware.

--
Some informative links:
news:news.announce.newusers
http://www.geocities.com/nnqweb/
http://www.catb.org/~esr/faqs/smart-questions.html
http://www.caliburn.nl/topposting.html
http://www.netmeister.org/news/learn2quote.html

Feb 25 '06 #4
Thank u to everyone!!!
i use gets () for the input before and now the "eco effect" has ended.
The input before was a string. With gets () i have a message of worning
with scanf () no.
The trouth shown me i have problems with the opposite.
I use gcc 3.4, i hope the 4 hasn't this problems.

Bye bye!!!
Aleramo.

Feb 25 '06 #5
Aleramo wrote:
Thank u to everyone!!!
i use gets () for the input [...]


No! No! Do not use gets()! diabolico!

http://c-faq.com/stdio/getsvsfgets.html

--
Eric Sosman
es*****@acm-dot-org.invalid

Feb 25 '06 #6
Aleramo wrote:

Thank u to everyone!!!
i use gets () for the input before and now the "eco effect" has ended.
The input before was a string. With gets () i have a message of worning
with scanf () no.
The trouth shown me i have problems with the opposite.
I use gcc 3.4, i hope the 4 hasn't this problems.


Never ever use gets. Do include adequate context with your
messages, and don't assume that the distorted google view of usenet
is accurate. Read the following sig, and read the references
therein, before replying again.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
Feb 26 '06 #7
"Aleramo" <mo************@yahoo.it> writes:
Thank u to everyone!!!
i use gets () for the input before and now the "eco effect" has ended.
The input before was a string. With gets () i have a message of worning
with scanf () no.
The trouth shown me i have problems with the opposite.
I use gcc 3.4, i hope the 4 hasn't this problems.


Never use gets. It cannot be used safely.

Never use silly abbreviations like "u" for "you"; they just make your
text more difficult to read.

Never post a followup via Google without first reading
<http://cfaj.freeshell.org/google/>.

--
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.
Feb 26 '06 #8
Keith Thompson wrote:
"Aleramo" <mo************@yahoo.it> writes:
Thank u to everyone!!!
i use gets () for the input before and now the "eco effect" has
ended. The input before was a string. With gets () i have a
message of worning with scanf () no.
The trouth shown me i have problems with the opposite.
I use gcc 3.4, i hope the 4 hasn't this problems.


Never use gets. It cannot be used safely.

Never use silly abbreviations like "u" for "you"; they just make
your text more difficult to read.

Never post a followup via Google without first reading
<http://cfaj.freeshell.org/google/>.


I wonder if he got the idea from this chorus of replies :-)

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
Feb 26 '06 #9
Maybe i made a few of confusion. I addict some rows before:

char scelta_array [10], scelta_piano ;

puts ("Scrivere:\n* lineare, per studiare un array lineare;") ;
puts ("* piano, per studiare un array piano;") ;
puts ("* qualunque altra parola per uscire.") ;
gets (scelta_array) ; /* Con scanf () non funziona!!! con gets
d il messaggio di worning ma non ga eco. */

do {
printf ("\nCome devono essere posizionati gli elementi?\n") ;
printf ("* premere E, nel caso di posizionamento sul piano
E\n") ;
printf ("(ricezione onde orizzontali);\n") ;
printf ("* premere H, nel caso di posizionamento sul piano
H\n") ;
printf ("(ricezione onde verticali).\n") ;
scanf ("%c", &scelta_piano) ;
} while ((scelta_piano != 'H') && (scelta_piano != 'h') &&
(scelta_piano != 'E') && (scelta_piano != 'e')) ;

Before i used:

scanf ("%s", scelta_array) ;

and i substituted it with:

gets (scelta_array) ;

I receive the message of Worning for gets (), but i can execute the
program withouth any problems. My question is: have you thought i
changet the scanf () in the cycle with the gets () ? it's the gets ()
there ok? or you advise me to change the solution?

Thank you to everyone!!!
Aleramo.

Feb 26 '06 #10
Aleramo wrote:
Maybe i made a few of confusion. I addict some rows before:

char scelta_array [10], scelta_piano ;

puts ("Scrivere:\n* lineare, per studiare un array lineare;") ;
puts ("* piano, per studiare un array piano;") ;
puts ("* qualunque altra parola per uscire.") ;
gets (scelta_array) ; /* Con scanf () non funziona!!! con gets
d il messaggio di worning ma non ga eco. */

do {
printf ("\nCome devono essere posizionati gli elementi?\n") ;
printf ("* premere E, nel caso di posizionamento sul piano
E\n") ;
printf ("(ricezione onde orizzontali);\n") ;
printf ("* premere H, nel caso di posizionamento sul piano
H\n") ;
printf ("(ricezione onde verticali).\n") ;
scanf ("%c", &scelta_piano) ;
} while ((scelta_piano != 'H') && (scelta_piano != 'h') &&
(scelta_piano != 'E') && (scelta_piano != 'e')) ;

Before i used:

scanf ("%s", scelta_array) ;

and i substituted it with:

gets (scelta_array) ;

I receive the message of Worning for gets (), but i can execute the
program withouth any problems. My question is: have you thought i
changet the scanf () in the cycle with the gets () ? it's the gets ()
there ok? or you advise me to change the solution?

Thank you to everyone!!!
Aleramo.

Don't use gets() as it does not allow you to control the number of
characters to be read into the buffer. This leads to buffer overrun when
gets() tries to write beyond the supplied buffer. With fgets() you can
control the number of characters to be read and thus prevent buffer
overruns.

Also, have a look at http://c-faq.com/stdio/getsvsfgets.html as Eric
Sosman already stated.
Feb 26 '06 #11
Aleramo wrote:
.... snip ...
I receive the message of Worning for gets (), but i can execute the
program withouth any problems. My question is: have you thought i
changet the scanf () in the cycle with the gets () ? it's the gets ()
there ok? or you advise me to change the solution?


Then why are you using it? Never use gets. You seem to have paid
zero attention to a fairly complete solution I offered you
yesterday, involving a generalized prompt and get response
mechanism.

--
Some similarities between GWB and Mussolini:
a) The strut; b) Making war until brought up short:
Mussolini: Ethiopia, France, Greece.
GWB: Afghanistan, Iraq.
Feb 26 '06 #12

"Aleramo" <mo************@yahoo.it> wrote in message
news:11**********************@z34g2000cwc.googlegr oups.com...
Maybe i made a few of confusion. I addict some rows before:

char scelta_array [10], scelta_piano ;

puts ("Scrivere:\n* lineare, per studiare un array lineare;") ;
puts ("* piano, per studiare un array piano;") ;
puts ("* qualunque altra parola per uscire.") ;
gets (scelta_array) ; /* Con scanf () non funziona!!! con gets
d il messaggio di worning ma non ga eco. */

do {
printf ("\nCome devono essere posizionati gli elementi?\n") ;
printf ("* premere E, nel caso di posizionamento sul piano
E\n") ;
printf ("(ricezione onde orizzontali);\n") ;
printf ("* premere H, nel caso di posizionamento sul piano
H\n") ;
printf ("(ricezione onde verticali).\n") ;
scanf ("%c", &scelta_piano) ;
} while ((scelta_piano != 'H') && (scelta_piano != 'h') &&
(scelta_piano != 'E') && (scelta_piano != 'e')) ;

Before i used:

scanf ("%s", scelta_array) ;

and i substituted it with:

gets (scelta_array) ;

I receive the message of Worning for gets (), but i can execute the
program withouth any problems. My question is: have you thought i
changet the scanf () in the cycle with the gets () ? it's the gets ()
there ok? or you advise me to change the solution?

Your original line

scanf ("%s", scelta_array) ;

had two problems. One is that it doesn't discard the '\n' at end-of-line.
The other is the buffer overrun.

Using gets() is a fix for the '\n' problem. But it doesn't do anything
about the buffer overrun. It doesn't make it any worse than it was before,
it just gets the compiler and everybody else pointing it out.

Sadly, fgets() doesn't help much. Unlike gets(), it doesn't always read a
line. It avoids a buffer overrun at the risk of leaving surplus input in
the input stream, which is the problem you had to start with.

Incidentally, if you type an X instead of an H or an E, don't you get the
echo thing again?
--
RSH

Feb 26 '06 #13
Robin Haigh wrote:

Your original line

scanf ("%s", scelta_array) ;

had two problems. One is that it doesn't discard the '\n' at end-of-line.
The other is the buffer overrun.


His original line was

scanf ("%c", &scelta_piano);

.... so it had only one of the two problems you mention.

--
Eric Sosman
es*****@acm-dot-org.invalid
Feb 26 '06 #14
Eric Sosman <es*****@acm-dot-org.invalid> wrote:
Aleramo wrote:
Thank u to everyone!!!
i use gets () for the input [...]


No! No! Do not use gets()! diabolico!

http://c-faq.com/stdio/getsvsfgets.html


Do you think it would help convince the Committee that gets() should go
if we cross-posted this to comp.std.c? Probably not :-/

Richard
Feb 28 '06 #15

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by William C. White | last post: by
2 posts views Thread by Albert Ahtenberg | last post: by
3 posts views Thread by James | last post: by
reply views Thread by Ollivier Robert | last post: by
1 post views Thread by Richard Galli | last post: by
4 posts views Thread by Albert Ahtenberg | last post: by
1 post views Thread by inderjit S Gabrie | last post: by
2 posts views Thread by Jack | last post: by
3 posts views Thread by Sandwick | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.