472,985 Members | 2,908 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

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
14 1626
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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: William C. White | last post by:
Does anyone know of a way to use PHP /w Authorize.net AIM without using cURL? Our website is hosted on a shared drive and the webhost company doesn't installed additional software (such as cURL)...
2
by: Albert Ahtenberg | last post by:
Hello, I don't know if it is only me but I was sure that header("Location:url") redirects the browser instantly to URL, or at least stops the execution of the code. But appearantely it continues...
3
by: James | last post by:
Hi, I have a form with 2 fields. 'A' 'B' The user completes one of the fields and the form is submitted. On the results page I want to run a query, but this will change subject to which...
0
by: Ollivier Robert | last post by:
Hello, I'm trying to link PHP with Oracle 9.2.0/OCI8 with gcc 3.2.3 on a Solaris9 system. The link succeeds but everytime I try to run php, I get a SEGV from inside the libcnltsh.so library. ...
1
by: Richard Galli | last post by:
I want viewers to compare state laws on a single subject. Imagine a three-column table with a drop-down box on the top. A viewer selects a state from the list, and that state's text fills the...
4
by: Albert Ahtenberg | last post by:
Hello, I have two questions. 1. When the user presses the back button and returns to a form he filled the form is reseted. How do I leave there the values he inserted? 2. When the...
1
by: inderjit S Gabrie | last post by:
Hi all Here is the scenerio ...is it possibly to do this... i am getting valid course dates output on to a web which i have designed ....all is okay so far , look at the following web url ...
2
by: Jack | last post by:
Hi All, What is the PHP equivilent of Oracle bind variables in a SQL statement, e.g. select x from y where z=:parameter Which in asp/jsp would be followed by some statements to bind a value...
3
by: Sandwick | last post by:
I am trying to change the size of a drawing so they are all 3x3. the script below is what i was trying to use to cut it in half ... I get errors. I can display the normal picture but not the...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
4
NeoPa
by: NeoPa | last post by:
Hello everyone. I find myself stuck trying to find the VBA way to get Access to create a PDF of the currently-selected (and open) object (Form or Report). I know it can be done by selecting :...
1
by: Teri B | last post by:
Hi, I have created a sub-form Roles. In my course form the user selects the roles assigned to the course. 0ne-to-many. One course many roles. Then I created a report based on the Course form and...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be focusing on the Report (clsReport) class. This simply handles making the calling Form invisible until all of the Reports opened by it have been closed, when it...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...

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.