471,571 Members | 1,002 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

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

scanf (yes/no) - doesn't work + deprecation errors scanf, fopen etc.

Hi,

Consider:
------------
char stringinput[64]

..bla. bla. bla.

do
{
printf("Write to result.txt (y/n)? ");
scanf("%s", stringinput);
}
while (writechar != 'y' || != 'n');
The compiler complaints. It says: error C2059: syntax error : '!='

Another problem is that MS VS 2005 keeps complaining about deprecated
commands such as:

1. warning C4996: 'fscanf' was declared deprecated.......: see
declaration of 'fscanf' - Message: 'This function or variable may be
unsafe. Consider using fscanf_s instead. To disable deprecation, use
_CRT_SECURE_NO_DEPRECATE. See online help for details.'

2. warning C4996: 'scanf' was declared deprecated: see declaration of
'scanf'... Message: 'This function or variable may be unsafe. Consider
using scanf_s instead. To disable deprecation, use ...

3. warning C4996: 'fopen' was declared deprecated.... : see declaration
of 'fopen' Message: 'This function or variable may be unsafe. Consider
using fopen_s instead. To disable deprecation, use
_CRT_SECURE_NO_DEPRECATE. See online help for details.'
How do I fix these problems? Sorry, but I'm not very experienced with C
programming.
Med venlig hilsen / Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Feb 16 '06 #1
185 16421
Martin Jørgensen wrote:
Hi,

Consider:
------------
char stringinput[64]

.bla. bla. bla.

do
{
printf("Write to result.txt (y/n)? ");
scanf("%s", stringinput);
}
while (writechar != 'y' || != 'n'); This should be :
while (writechar != 'y' || writechar != 'n');


The compiler complaints. It says: error C2059: syntax error : '!='

Another problem is that MS VS 2005 keeps complaining about deprecated
commands such as:

1. warning C4996: 'fscanf' was declared deprecated.......: see
declaration of 'fscanf' - Message: 'This function or variable may be
unsafe. Consider using fscanf_s instead. To disable deprecation, use
_CRT_SECURE_NO_DEPRECATE. See online help for details.'

2. warning C4996: 'scanf' was declared deprecated: see declaration of
'scanf'... Message: 'This function or variable may be unsafe. Consider
using scanf_s instead. To disable deprecation, use ...

3. warning C4996: 'fopen' was declared deprecated.... : see declaration
of 'fopen' Message: 'This function or variable may be unsafe. Consider
using fopen_s instead. To disable deprecation, use
_CRT_SECURE_NO_DEPRECATE. See online help for details.'
How do I fix these problems? Sorry, but I'm not very experienced with C
programming.
Med venlig hilsen / Best regards
Martin Jørgensen


Feb 16 '06 #2
Martin Jørgensen wrote:
[...]
while (writechar != 'y' || != 'n');

The compiler complaints. It says: error C2059: syntax error : '!='


Of course! If _what_ is not equal to 'n'?

I assume you meant:

while (writechar != 'y' && writechar != 'n');

That is, until writechar is either 'y' or 'n'. Is that what you meant?

Remember that you need "&&" for "and", not "||" for "or". Otherwise,
the statement will always be true, as it can't be equal to both.

[...]

--
+-------------------------+--------------------+-----------------------------+
| Kenneth J. Brody | www.hvcomputer.com | |
| kenbrody/at\spamcop.net | www.fptech.com | #include <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------------+
Don't e-mail me at: <mailto:Th*************@gmail.com>

Feb 16 '06 #3

"Martin Jørgensen" <un*********@spam.jay.net> wrote in message
news:fq***********@news.tdc.dk...
Hi,

Consider:
------------
char stringinput[64]

.bla. bla. bla.

do
{
printf("Write to result.txt (y/n)? ");
scanf("%s", stringinput);
}
while (writechar != 'y' || != 'n');
What is writechar? Presumabley of type char.

The snippet !='n' is illegal syntax after the || operator.
You can't say "a is not b or not c", you must say
"a is not b or a is not c"
or, better yet,
"(a is not b) or (a is not c)"

Also, the logic here is probably not what you want, since
(writechar != 'y') || (writechar != 'n')
is always true. You probably want && instread of ||

<snip>> Med venlig hilsen / Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk


--
Fred L. Kleinschmidt
Boeing Associate Technical Fellow
Technical Architect, Software Reuse Project
Feb 16 '06 #4
This code will do what you want...

#include <stdio.h>

int main(void)
{
char stringInput;

do
{
printf("\nWrite to result.txt (y/n)? ");
stringInput = getchar();
__fpurge(stdin); // clear the stdin to strip off the previous newline char.
}
while (stringInput != 'y' && stringInput != 'n');

printf("Thank you very much\n");

return 0;
}

greetzz,

Broeisi

Martin Jørgensen wrote:
Hi,

Consider:
------------
char stringinput[64]

.bla. bla. bla.

do
{
printf("Write to result.txt (y/n)? ");
scanf("%s", stringinput);
}
while (writechar != 'y' || != 'n');
The compiler complaints. It says: error C2059: syntax error : '!='

Another problem is that MS VS 2005 keeps complaining about deprecated
commands such as:

1. warning C4996: 'fscanf' was declared deprecated.......: see
declaration of 'fscanf' - Message: 'This function or variable may be
unsafe. Consider using fscanf_s instead. To disable deprecation, use
_CRT_SECURE_NO_DEPRECATE. See online help for details.'

2. warning C4996: 'scanf' was declared deprecated: see declaration of
'scanf'... Message: 'This function or variable may be unsafe. Consider
using scanf_s instead. To disable deprecation, use ...

3. warning C4996: 'fopen' was declared deprecated.... : see declaration
of 'fopen' Message: 'This function or variable may be unsafe. Consider
using fopen_s instead. To disable deprecation, use
_CRT_SECURE_NO_DEPRECATE. See online help for details.'
How do I fix these problems? Sorry, but I'm not very experienced with C
programming.
Med venlig hilsen / Best regards
Martin Jørgensen


Feb 16 '06 #5
Broeisi wrote:
This code will do what you want...
Yep, you must be a mind reader or something :-)
#include <stdio.h>

int main(void)
{
char stringInput;

do
{
printf("\nWrite to result.txt (y/n)? ");
stringInput = getchar();
__fpurge(stdin); // clear the stdin to strip off the previous newline char.
}
while (stringInput != 'y' && stringInput != 'n');

printf("Thank you very much\n");

return 0;
}

greetzz,


Thanks. But your program doesn't work on my pc. There was something
wrong with "__fpurge(stdin);" - I use MS visual studio 2005.

I'm still struggling with how to make the following work now:

do
{
printf("Write to file? (y/n): ");
}

while (writechar != 'y' || writechar != 'n');

Now I just made writechar of type "char". I don't know what to do with
this return \n, but I assume it is a problem... Thanks for anything.

BTW: Yep, you're all right. I made a stupid mistake before with the
logical test...

Med venlig hilsen / Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Feb 16 '06 #6
On Thu, 16 Feb 2006 13:09:03 -0600, Broeisi <br*******@gmail.com>
wrote:
This code will do what you want...

#include <stdio.h>

int main(void)
{
char stringInput;

do
{
printf("\nWrite to result.txt (y/n)? ");
stringInput = getchar();
__fpurge(stdin); // clear the stdin to strip off the previous newline char. ???__ fpurge? What page of the standard is that on? }
while (stringInput != 'y' && stringInput != 'n');

printf("Thank you very much\n");

return 0;
}

greetzz,

Broeisi

Martin Jørgensen wrote:
Hi,

Consider:
------------
char stringinput[64]

.bla. bla. bla.

do
{
printf("Write to result.txt (y/n)? ");
scanf("%s", stringinput);
}
while (writechar != 'y' || != 'n');
The compiler complaints. It says: error C2059: syntax error : '!='

Another problem is that MS VS 2005 keeps complaining about deprecated
commands such as:

1. warning C4996: 'fscanf' was declared deprecated.......: see
declaration of 'fscanf' - Message: 'This function or variable may be
unsafe. Consider using fscanf_s instead. To disable deprecation, use
_CRT_SECURE_NO_DEPRECATE. See online help for details.'

2. warning C4996: 'scanf' was declared deprecated: see declaration of
'scanf'... Message: 'This function or variable may be unsafe. Consider
using scanf_s instead. To disable deprecation, use ...

3. warning C4996: 'fopen' was declared deprecated.... : see declaration
of 'fopen' Message: 'This function or variable may be unsafe. Consider
using fopen_s instead. To disable deprecation, use
_CRT_SECURE_NO_DEPRECATE. See online help for details.'
How do I fix these problems? Sorry, but I'm not very experienced with C
programming.
Med venlig hilsen / Best regards
Martin Jørgensen


--
Al Balmer
Sun City, AZ
Feb 16 '06 #7
Broeisi <br*******@gmail.com> writes:
This code will do what you want...

#include <stdio.h>

int main(void)
{
char stringInput;

do
{
printf("\nWrite to result.txt (y/n)? ");
stringInput = getchar();
__fpurge(stdin); // clear the stdin to strip off the previous newline char.
}
while (stringInput != 'y' && stringInput != 'n');

printf("Thank you very much\n");

return 0;
}


There is no __fpurge() function in standard C. If you want to consume
the rest of the input line up to the new-line character, it's easy
enought to do it in standard C.

--
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 16 '06 #8
Martin Jørgensen <un*********@spam.jay.net> writes:
Consider:
------------
char stringinput[64]

.bla. bla. bla.

do
{
printf("Write to result.txt (y/n)? ");
scanf("%s", stringinput);
}
while (writechar != 'y' || != 'n');
The compiler complaints. It says: error C2059: syntax error : '!='

Another problem is that MS VS 2005 keeps complaining about deprecated
commands such as:

1. warning C4996: 'fscanf' was declared deprecated.......: see
declaration of 'fscanf' - Message: 'This function or variable may be
unsafe. Consider using fscanf_s instead. To disable deprecation, use
_CRT_SECURE_NO_DEPRECATE. See online help for details.'

2. warning C4996: 'scanf' was declared deprecated: see declaration of
'scanf'... Message: 'This function or variable may be unsafe. Consider
using scanf_s instead. To disable deprecation, use ...

3. warning C4996: 'fopen' was declared deprecated.... : see
declaration of 'fopen' Message: 'This function or variable may be
unsafe. Consider using fopen_s instead. To disable deprecation, use
_CRT_SECURE_NO_DEPRECATE. See online help for details.'


fscanf(), scanf(), and fopen() are standard functions. Your compiler
is trying to tell you to replace them with fscanf_s(), scanf_s(), and
fopen_s(), which are not standard. You can do so if you like, and the
resulting code just might be safer, but it won't be portable (and we
won't be able to help you with it here).

If you want to program in standard C, you can disable the warnings;
your compiler is telling you how to do that.

--
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 16 '06 #9
On Thu, 16 Feb 2006 18:19:42 +0100, Martin Jørgensen
<un*********@spam.jay.net> wrote in comp.lang.c:
Hi,

Consider:
------------
char stringinput[64]

.bla. bla. bla.

do
{
printf("Write to result.txt (y/n)? ");
scanf("%s", stringinput);


Microsoft is on mission to replace some of the more
dangerous-when-misused functions in C with safer versions. This is
something that has been proposed for a future version of the C
language standard, but is not part of the official language now.

But in the particular case above, they are absolutely right, because
you are misusing scanf() and making it very, very dangerous. You
could be writing the next flawed program to be targeted by a buffer
overflow exploit to turn computers into bots used by internet
criminals.

Never, never, NEVER use scanf (or fscanf or sscanf) with "%s" without
specifying a maximum length. You have an array of 64 characters. You
have told scanf() to accept as many characters as it can find in the
standard input before a white space. What if the user types 100
characters, or 1000 characters, or even 65 characters? What do you
think is going to happen when scanf() tries to keep on inserting
characters way past the end of the array?

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Feb 17 '06 #10
Keith Thompson wrote:
Martin Jørgensen <un*********@spam.jay.net> writes:

.... snip ...

Another problem is that MS VS 2005 keeps complaining about deprecated
commands such as:

1. warning C4996: 'fscanf' was declared deprecated.......: see
declaration of 'fscanf' - Message: 'This function or variable may be
unsafe. Consider using fscanf_s instead. To disable deprecation, use
_CRT_SECURE_NO_DEPRECATE. See online help for details.'

2. warning C4996: 'scanf' was declared deprecated: see declaration of
'scanf'... Message: 'This function or variable may be unsafe. Consider
using scanf_s instead. To disable deprecation, use ...

3. warning C4996: 'fopen' was declared deprecated.... : see
declaration of 'fopen' Message: 'This function or variable may be
unsafe. Consider using fopen_s instead. To disable deprecation, use
_CRT_SECURE_NO_DEPRECATE. See online help for details.'


fscanf(), scanf(), and fopen() are standard functions. Your compiler
is trying to tell you to replace them with fscanf_s(), scanf_s(), and
fopen_s(), which are not standard. You can do so if you like, and the
resulting code just might be safer, but it won't be portable (and we
won't be able to help you with it here).

If you want to program in standard C, you can disable the warnings;
your compiler is telling you how to do that.


You might have pointed out that, as usual, Microsoft is
contravening standards in an effort to get people locked into their
non-standard code, so that they can sell more buggy software.

--
"The power of the Executive to cast a man into prison without
formulating any charge known to the law, and particularly to
deny him the judgement of his peers, is in the highest degree
odious and is the foundation of all totalitarian government
whether Nazi or Communist." -- W. Churchill, Nov 21, 1943
Feb 17 '06 #11
Jack Klein <ja*******@spamcop.net> writes:
[...]
Never, never, NEVER use scanf (or fscanf or sscanf) with "%s" without
specifying a maximum length. You have an array of 64 characters. You
have told scanf() to accept as many characters as it can find in the
standard input before a white space. What if the user types 100
characters, or 1000 characters, or even 65 characters? What do you
think is going to happen when scanf() tries to keep on inserting
characters way past the end of the array?


It might be reasonable to use sscanf with "%s" if you have sufficient
control over the string being scanned (i.e., if you *know* it can't
overflow). The same thing might theoretically apply to fscanf(), but
it's less safe to assume that an external file contains what you
expect it to. Except under the rarest circumstances, you should
assume that stdin (used by scanf) could contain any arbitrary data,
and guard against it.

But it's safer and easier to avoid "%s" altogether, for all the *scanf
functions.

--
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 17 '06 #12
CBFalconer <cb********@yahoo.com> writes:
Keith Thompson wrote:

[...]
fscanf(), scanf(), and fopen() are standard functions. Your compiler
is trying to tell you to replace them with fscanf_s(), scanf_s(), and
fopen_s(), which are not standard. You can do so if you like, and the
resulting code just might be safer, but it won't be portable (and we
won't be able to help you with it here).

If you want to program in standard C, you can disable the warnings;
your compiler is telling you how to do that.


You might have pointed out that, as usual, Microsoft is
contravening standards in an effort to get people locked into their
non-standard code, so that they can sell more buggy software.


I might have, but it didn't seem relevant, and doesn't appear to be
true in this case. The *_s functions look similar to, and may
actually be, the functions defined in n1135,
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1135.pdf>, which is
an ISO/IEC draft Technical Report.

--
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 17 '06 #13
Keith Thompson wrote:
.... snip ...
I might have, but it didn't seem relevant, and doesn't appear to be
true in this case. The *_s functions look similar to, and may
actually be, the functions defined in n1135,
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1135.pdf>, which is
an ISO/IEC draft Technical Report.


This is the first I had heard of that. Took a quick look, and I
think it is ignoring real work going on in the C world. Glaringly
obvious are missing references to strlcat and strlcpy from FreeBSD,
which make much more sense than the proposals.

I also think the gets_s proposal is foolish. Novices use gets
because it is simple and minimizes thought. My own ggets attempts
to fill that need.

Cross posted to c.std.c. For reference source etc. for strlcat,
strlcpy, and ggets are available at:

<http://cbfalconer.home.att.net/download/strlcpy.zip>
<http://cbfalconer.home.att.net/download/ggets.zip>

--
"The most amazing achievement of the computer software industry
is its continuing cancellation of the steady and staggering
gains made by the computer hardware industry..." - Petroski
Feb 17 '06 #14
CBFalconer <cb********@yahoo.com> wrote:
Keith Thompson wrote:

I might have, but it didn't seem relevant, and doesn't appear to be
true in this case. The *_s functions look similar to, and may
actually be, the functions defined in n1135,
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1135.pdf>, which is
an ISO/IEC draft Technical Report.
This is the first I had heard of that. Took a quick look, and I
think it is ignoring real work going on in the C world.


I think a hint to that, and to the reason why Microsoft "adopted" this
"standard" with such suspicious dispatch, may lie in the origin of the
proposal.
I also think the gets_s proposal is foolish. Novices use gets
because it is simple and minimizes thought. My own ggets attempts
to fill that need.


Which is also missing the point, and in the same way that n1135 does.

This proposal, and your ggets(), will _perhaps_ be adopted by only those
programmers who already take care to program safely. Hacks will ignore
them.

Richard
Feb 17 '06 #15
Keith Thompson wrote:
Jack Klein <ja*******@spamcop.net> writes:
[...]
Never, never, NEVER use scanf (or fscanf or sscanf) with "%s" without
specifying a maximum length. You have an array of 64 characters. You
have told scanf() to accept as many characters as it can find in the
standard input before a white space. What if the user types 100
characters, or 1000 characters, or even 65 characters? What do you
think is going to happen when scanf() tries to keep on inserting
characters way past the end of the array?

Crash.
It might be reasonable to use sscanf with "%s" if you have sufficient
control over the string being scanned (i.e., if you *know* it can't
overflow). The same thing might theoretically apply to fscanf(), but
it's less safe to assume that an external file contains what you
expect it to. Except under the rarest circumstances, you should
assume that stdin (used by scanf) could contain any arbitrary data,
and guard against it.
Ok.
But it's safer and easier to avoid "%s" altogether, for all the *scanf
functions.


Sorry for my late reply... But good point there. How about scanf("%20s",
string) or something?
Med venlig hilsen / Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Feb 17 '06 #16
Keith Thompson wrote:
-snip-
If you want to program in standard C, you can disable the warnings;
your compiler is telling you how to do that.


Yep, I did that. Much, much better now :-)
Med venlig hilsen / Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Feb 17 '06 #17
Martin Jørgensen schrieb:
Keith Thompson wrote:
Jack Klein <ja*******@spamcop.net> writes:
[...]
Never, never, NEVER use scanf (or fscanf or sscanf) with "%s" without
specifying a maximum length. You have an array of 64 characters. You
have told scanf() to accept as many characters as it can find in the
standard input before a white space. What if the user types 100
characters, or 1000 characters, or even 65 characters? What do you
think is going to happen when scanf() tries to keep on inserting
characters way past the end of the array?
Crash.


The ugly thing is: Not necessarily.
It may only happen when Mars occupies a corner in Jupiter's House
or your boss, customer, or whoever stands at your side for the
crucial demonstration. All other times it seems to work.

It might be reasonable to use sscanf with "%s" if you have sufficient
control over the string being scanned (i.e., if you *know* it can't
overflow). The same thing might theoretically apply to fscanf(), but
it's less safe to assume that an external file contains what you
expect it to. Except under the rarest circumstances, you should
assume that stdin (used by scanf) could contain any arbitrary data,
and guard against it.


Ok.
But it's safer and easier to avoid "%s" altogether, for all the *scanf
functions.


Sorry for my late reply... But good point there. How about scanf("%20s",
string) or something?


The thing is, you still cannot control what you get -- whitespace
still gets discarded unless you use scan sets (e.g. %40[ \t\naA]).
Using fgets() or a homebrew getch()-based input usually is safer.
You can also use ggets() which can be written in standard C; Chuck
Falconer advertises his public domain version around here.

Another thing: There is no equivalent to the run-time determination
of field width and precision for printf(). If you do not want to
have magic numbers you always have something like that:

#define STRINGIZE(S) #s
#define XSTR(S) STRINGIZE(S)

#define BUFSIZE 20

....
char buffer[BUFSIZE+1];
....
ret = sscanf("%" XSTR(BUFSIZE) "s", buffer);
....

Not really what I'd call flexible. And I am a friend of sscanf().
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Feb 17 '06 #18
Michael Mair wrote:
Martin Jørgensen schrieb: -snip-
characters, or 1000 characters, or even 65 characters? What do you
think is going to happen when scanf() tries to keep on inserting
characters way past the end of the array?

Crash.

The ugly thing is: Not necessarily.


Yeah, ok. I just debugged a program yesterday which took me very long
time before it crashed... Of course the error was also very difficult to
find.... So it was really annoying just to find out that I had an array
operation; something like var[variable+2]=(code) and forgot to declare
it var[variable+3] instead of var[variable+2]... Damn, I hope I learned
my lesson :-)

-snip-
Sorry for my late reply... But good point there. How about
scanf("%20s", string) or something?

The thing is, you still cannot control what you get -- whitespace
still gets discarded unless you use scan sets (e.g. %40[ \t\naA]).
Using fgets() or a homebrew getch()-based input usually is safer.
You can also use ggets() which can be written in standard C; Chuck
Falconer advertises his public domain version around here.


Ok.
Another thing: There is no equivalent to the run-time determination
of field width and precision for printf(). If you do not want to
have magic numbers you always have something like that:

#define STRINGIZE(S) #s
#define XSTR(S) STRINGIZE(S)

#define BUFSIZE 20

...
char buffer[BUFSIZE+1];
....
ret = sscanf("%" XSTR(BUFSIZE) "s", buffer);
....

Not really what I'd call flexible. And I am a friend of sscanf().


Thanks for the code piece. I wish my (lousy?) C programming book used
sscanf() instead, like you propose...
Med venlig hilsen / Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Feb 17 '06 #19
On Thu, 16 Feb 2006 12:29:29 -0600, Broeisi <br*******@gmail.com>
wrote:
Martin Jørgensen wrote:
Hi,

Consider:
------------
char stringinput[64]

.bla. bla. bla.

do
{
printf("Write to result.txt (y/n)? ");
scanf("%s", stringinput);
}
while (writechar != 'y' || != 'n');

This should be :
while (writechar != 'y' || writechar != 'n');


While it is now syntactically correct, the expression will always
evaluate to true. Use &&, not ||.

Remove del for email
Feb 18 '06 #20
Barry Schwarz wrote:
-snip-
This should be :
while (writechar != 'y' || writechar != 'n');

While it is now syntactically correct, the expression will always
evaluate to true. Use &&, not ||.


Damn... Thanks...
Med venlig hilsen / Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Feb 18 '06 #21
"Michael Mair" <Mi**********@invalid.invalid> skrev i en meddelelse
news:45************@individual.net...
-snip-
Another thing: There is no equivalent to the run-time determination
of field width and precision for printf(). If you do not want to
have magic numbers you always have something like that:

#define STRINGIZE(S) #s
#define XSTR(S) STRINGIZE(S)

#define BUFSIZE 20

...
char buffer[BUFSIZE+1];
....
ret = sscanf("%" XSTR(BUFSIZE) "s", buffer);
....

Not really what I'd call flexible. And I am a friend of sscanf().


How about using getchar() like this for a yes/no test:

printf("Write to file result.txt (y/n)? ");
while ( tolower(writechar = getchar() ) != 'y' && tolower(writechar) != 'n')
{
if (writechar != '\n')
printf("Write to file result.txt (y/n)? ");
};

if (tolower(writechar) == 'j')
bla. bla. (write to file)
if no, then quit etc...
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Feb 18 '06 #22
Broeisi a écrit :
This code will do what you want... __fpurge(stdin); // clear the stdin to strip off the previous newline char.


Bad avice. This function is not standard.

You should use fgets() with an array of 3 (at least) char...

--
A+

Emmanuel Delahaye
Feb 18 '06 #23
"Martin Joergensen" <un*********@spam.jay.net> wrote in message
news:td************@news.tdc.dk...
How about using getchar() like this for a yes/no test:
It would be better if you posted a fully compilable program. I assume you
included <ctype.h> and declared writechar as int. There are still some
problems with your implementation.
printf("Write to file result.txt (y/n)? ");
while ( tolower(writechar = getchar() ) != 'y' && tolower(writechar) != 'n') {
if (writechar != '\n')
printf("Write to file result.txt (y/n)? ");
};


You are not taking into account that a call to getchar() may return EOF
except for a character. This may happen if end of file is encountered or in
case of an error.

What happens if the user of your program types more than one character and
then presses <Enter>?
1) If the first character is one of those you are looking for
('y','n','Y','N'), the while loop exits and the rest of the typed characters
still reside in stdin. If you read the stdin later on, you will first read
those characters.
2) If the first character is not one of the expected ones, the message
printed in the body of your loop, will be printed repeatedly until all
characters in the stdin are consumed.
I do not think this is the behaviour you desire, so you should focus on
fixing these problems.
Feb 18 '06 #24
stathis gotsis wrote:
"Martin Joergensen" <un*********@spam.jay.net> wrote in message
news:td************@news.tdc.dk... -snip-
You are not taking into account that a call to getchar() may return EOF
except for a character. This may happen if end of file is encountered or in
case of an error.
EOF when I read from keyboard?
What happens if the user of your program types more than one character and
then presses <Enter>?
Yeah, I know it's a problem I'm trying to fix...
1) If the first character is one of those you are looking for
('y','n','Y','N'), the while loop exits and the rest of the typed characters
still reside in stdin. If you read the stdin later on, you will first read
those characters.
2) If the first character is not one of the expected ones, the message
printed in the body of your loop, will be printed repeatedly until all
characters in the stdin are consumed.
I do not think this is the behaviour you desire, so you should focus on
fixing these problems.


#include <stdio.h>
#include <ctype.h>

#define buffer_length 2

main()
{
char writechar[buffer_length];

writechar[0]='a'; // initialize it to something other than y/n

while ( tolower(writechar[0] ) != 'y' && tolower(writechar[0]) != 'n')
{
if (writechar[0] != '\n')
printf("Write to the file result.txt (y/n)? ");
fgets(writechar, buffer_length, stdin);
}

if (tolower(writechar[0]) == 'y')
printf("You typed \"y\"\n");
else if (tolower(writechar[0]) == 'n')
printf("You typed \"n\"\n");
}
Now, even though I made "#define buffer_length 2" I would expect that if
the user typed something like "asdfa", then the question wouldn't be
printed 5 times... But it is printed 5 times... Without having to
download any libraries or whatever, how to fix this final problem? I
assume the definition of writechar is ok (or should be it an array of
length 3)?
Med venlig hilsen / Best regards
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Feb 18 '06 #25
Martin Jørgensen <un*********@spam.jay.net> writes:
stathis gotsis wrote:
"Martin Joergensen" <un*********@spam.jay.net> wrote in message
news:td************@news.tdc.dk... -snip-
You are not taking into account that a call to getchar() may return EOF
except for a character. This may happen if end of file is encountered or in
case of an error.


EOF when I read from keyboard?


Yes, of course, typically triggered by control-D or control-Z.

[snip]
#include <stdio.h>
#include <ctype.h>

#define buffer_length 2

main()
{
char writechar[buffer_length];

writechar[0]='a'; // initialize it to something other than y/n

while ( tolower(writechar[0] ) != 'y' && tolower(writechar[0]) != 'n')
{
if (writechar[0] != '\n')
printf("Write to the file result.txt (y/n)? ");
fgets(writechar, buffer_length, stdin);
}

if (tolower(writechar[0]) == 'y')
printf("You typed \"y\"\n");
else if (tolower(writechar[0]) == 'n')
printf("You typed \"n\"\n");
}
Now, even though I made "#define buffer_length 2" I would expect that
if the user typed something like "asdfa", then the question wouldn't
be printed 5 times... But it is printed 5 times... Without having to
download any libraries or whatever, how to fix this final problem? I
assume the definition of writechar is ok (or should be it an array of
length 3)?


If fgets() tries to read a line longer than the specified length
(buffer_length), the remainder of the line is left on the input
stream, to be read by the next call to fgets(). Repeated calls to
fgets() will read the entire line, a chunk at a time.

You probably don't want to examine every character on the input line,
just the first one. Or maybe you want to skip whitespace.

You can use fgets() with larger size argument to read the entire input
line into a string, then examine just the first character of the
string. If fgets() didn't read the entire line, the last character of
the string won't be a '\n' character; you can then discard the rest of
the line.

Or you can read a single character, check whether it's 'y' or 'n', and
then discard the rest of the line (up to the first '\n'). Decide what
you want to do on an empty input line (i.e., if the first character
you read is '\n'), and how you want to handle an EOF condition.

--
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 18 '06 #26
"Martin Jørgensen" <un*********@spam.jay.net> wrote in message
news:c2************@news.tdc.dk...
stathis gotsis wrote:
"Martin Joergensen" <un*********@spam.jay.net> wrote in message
news:td************@news.tdc.dk... -snip-
You are not taking into account that a call to getchar() may return EOF
except for a character. This may happen if end of file is encountered or in case of an error.


EOF when I read from keyboard?


Yes, it is possible when you type something like CTRL-D or CTRL-Z(It is
CTRL-Z typed at the start of the input line on a windows dos console). Also,
getchar() may return EOF in case of an error, so you should consider
comparing the return value of getchar() to EOF too.
#include <stdio.h>
#include <ctype.h>

#define buffer_length 2

main()
{
char writechar[buffer_length];

writechar[0]='a'; // initialize it to something other than y/n

while ( tolower(writechar[0] ) != 'y' && tolower(writechar[0]) != 'n')
{
if (writechar[0] != '\n')
printf("Write to the file result.txt (y/n)? ");
fgets(writechar, buffer_length, stdin);
fgets() will read up to (buffer_length-1 = 1) characters, so the problem
remains unsolved. Even if you increase buffer_lenth, the user might input
long lines so that fgets() does not read all of the input. I think you
should stick with your previous implementation where you used getchar(). You
will just have to read the first character each time, then eat up rest of
the input until you reach the newline. In all cases, handle EOF.
}

if (tolower(writechar[0]) == 'y')
printf("You typed \"y\"\n");
else if (tolower(writechar[0]) == 'n')
printf("You typed \"n\"\n");
}


Feb 19 '06 #27
Martin Jørgensen schrieb:
stathis gotsis wrote:
"Martin Joergensen" <un*********@spam.jay.net> wrote in message
news:td************@news.tdc.dk...


-snip-
You are not taking into account that a call to getchar() may return EOF
except for a character. This may happen if end of file is encountered
or in
case of an error.


EOF when I read from keyboard?


As the others have not mentioned it: You can redirect a file
to stdin on many systems. I like to do that for C courses;
redirect stdin/stdout/stderr and let a bash script or batch
file check whether everything has been done correctly...

Interestingly, if I feed the elsethread (*) posted get_double
programme with an invalid file (containing only ".\n"), the
programme is caught in an endless loop as I forgot to break
the loop on file end and file error conditions... ;-)
This was not a problem for interactive input as the EOF
condition was given once and afterwards the loop could
continue, but in this case, we always get EOF. So much for
sufficient error handling.

<snip>
Cheers
Michael

(*) <45************@individual.net>
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Feb 19 '06 #28
"stathis gotsis" <st***********@hotmail.com> skrev i en meddelelse
news:dt**********@ulysses.noc.ntua.gr...
-snip-
EOF when I read from keyboard?


Yes, it is possible when you type something like CTRL-D or CTRL-Z(It is
CTRL-Z typed at the start of the input line on a windows dos console).
Also,
getchar() may return EOF in case of an error, so you should consider
comparing the return value of getchar() to EOF too.


Ok, clear...
#include <stdio.h>
#include <ctype.h>

#define buffer_length 2

main()
{
char writechar[buffer_length];

writechar[0]='a'; // initialize it to something other than y/n

while ( tolower(writechar[0] ) != 'y' && tolower(writechar[0]) != 'n')
{
if (writechar[0] != '\n')
printf("Write to the file result.txt (y/n)? ");
fgets(writechar, buffer_length, stdin);


fgets() will read up to (buffer_length-1 = 1) characters, so the problem
remains unsolved. Even if you increase buffer_lenth, the user might input
long lines so that fgets() does not read all of the input. I think you
should stick with your previous implementation where you used getchar().
You
will just have to read the first character each time, then eat up rest of
the input until you reach the newline. In all cases, handle EOF.


Hmm. Okay, but I'm not really sure about how to discard the rest of the
line....... This program that was posted earlier had an error with the
__fpurge(stdin) - how do I modify it to work with standard C without
downloading any libraries or anything?:
#include <stdio.h>

int main(void)
{
char stringInput;

do
{
printf("\nWrite to result.txt (y/n)? ");
stringInput = getchar();
__fpurge(stdin); // clear the stdin to strip off the previous newline char.
}
while (stringInput != 'y' && stringInput != 'n');

printf("Thank you very much\n");

return 0;
}

Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Feb 19 '06 #29
Martin Joergensen schrieb:
"stathis gotsis" <st***********@hotmail.com> skrev i en meddelelse <snip!>
fgets() will read up to (buffer_length-1 = 1) characters, so the problem
remains unsolved. Even if you increase buffer_lenth, the user might input
long lines so that fgets() does not read all of the input. I think you
should stick with your previous implementation where you used getchar().
You
will just have to read the first character each time, then eat up rest of
the input until you reach the newline. In all cases, handle EOF.


Hmm. Okay, but I'm not really sure about how to discard the rest of the
line....... This program that was posted earlier had an error with the
__fpurge(stdin) - how do I modify it to work with standard C without
downloading any libraries or anything?:

#include <stdio.h>

int main(void)
{
char stringInput;

int tmp;
do
{
printf("\nWrite to result.txt (y/n)? ");
stringInput = getchar();
Hmmm, go back to the comp.lang.c FAQ and read it carefully.

getchar() returns int, where the characters are cast to
unsigned char and EOF is a negative int value.
Every character literal in C is of type int.
If you make stringInput type char you can miss EOF returns or
returns >= SCHAR_MAX.
__fpurge(stdin); // clear the stdin to strip off the previous newline char.
while (EOF != (tmp = getchar()))
if ('\n' == tmp)
break;
or
do {
tmp = getchar();
} while(EOF != tmp && '\n' != tmp);
}
while (stringInput != 'y' && stringInput != 'n');

printf("Thank you very much\n");

return 0;
}


Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Feb 19 '06 #30
Martin Joergensen wrote:
.... snip ...
Hmm. Okay, but I'm not really sure about how to discard the rest
of the line....... This program that was posted earlier had an
error with the __fpurge(stdin) - how do I modify it to work with
standard C without downloading any libraries or anything?:


int flushln(FILE *f)
{
int ch;

do {
ch = getc(f);
while ((EOF != ch) && ('\n' != ch));
return ch;
}

--
"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 19 '06 #31
Michael Mair wrote:
-snip-
__fpurge(stdin); // clear the stdin to strip off the previous newline
char.

while (EOF != (tmp = getchar()))
if ('\n' == tmp)
break;
or
do {
tmp = getchar();
} while(EOF != tmp && '\n' != tmp);


Thanks Michael. I took me really long time to realize that I needed two
integers (an extra int tmp). So it really works now.

I just don't really understand why it works... Let's look at my code
(int charInput, tmp;)

do
{
printf("\nWrite to result.txt (y/n)? ");
charInput = getchar();

do {
tmp = getchar();
} while(EOF != tmp && '\n' != tmp); // */

}
while (charInput != 'y' && charInput != 'n');
I did a little debugging and it seems like charInput always contains the
first character I enter, while tmp always contains "10" which AFAIR is \n.

Shouldn't the while line be changed to: } while(EOF != tmp || '\n' !=
tmp);? I mean: tmp can't be EOF and \n at the same time, can it?

I tried Ctrl+D on mac os x. Isn't that EOF? I'll try ctrl+D or ctrl+Z on
my windows machine later...
Best regards / Med venlig hilsen
Martin Jørgense

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Feb 19 '06 #32
Martin Jørgensen schrieb:
Michael Mair wrote:
-snip-
__fpurge(stdin); // clear the stdin to strip off the previous newline
char.
while (EOF != (tmp = getchar()))
if ('\n' == tmp)
break;
or
do {
tmp = getchar();
} while(EOF != tmp && '\n' != tmp);

Thanks Michael. I took me really long time to realize that I needed two
integers (an extra int tmp). So it really works now.

I just don't really understand why it works... Let's look at my code
(int charInput, tmp;)

do
{
printf("\nWrite to result.txt (y/n)? ");
charInput = getchar();

do {
tmp = getchar();
} while(EOF != tmp && '\n' != tmp); // */

}
while (charInput != 'y' && charInput != 'n');
I did a little debugging and it seems like charInput always contains the
first character I enter, while tmp always contains "10" which AFAIR is \n.

Shouldn't the while line be changed to: } while(EOF != tmp || '\n' !=
tmp);? I mean: tmp can't be EOF and \n at the same time, can it?


No. But the loop has to stop if tmp either equals EOF or equals '\n',
that is, it runs as long as tmp equals neither.

I tried Ctrl+D on mac os x. Isn't that EOF? I'll try ctrl+D or ctrl+Z on
my windows machine later...


I do not know about Mac OS X. Ctrl+Z works with Windows, Ctrl+D with
Linux or Cygwin.

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Feb 19 '06 #33
>Michael Mair wrote:
while (EOF != (tmp = getchar()))
if ('\n' == tmp)
break;
or
do {
tmp = getchar();
} while(EOF != tmp && '\n' != tmp);

In article <lh************@news.tdc.dk>
Martin Jørgensen <un*********@spam.jay.net> wrote:Thanks Michael. I took me really long time to realize that I needed two
integers (an extra int tmp). So it really works now.

I just don't really understand why it works...
OK, think of "stdin" as coming from a file, rather than from the
keyboard. (It works the same either way, except that when reading
from the keyboard, the "contents" cannot be predicted in advance
by peeking at the file. You would have to peek at the typist's
mind instead.)

If a file consists in its entirety of a pair of lines like this:

abcdefg
wxyz

then the contents of the stream, taken one character at a time, are:

'a', 'b', 'c', 'd', 'e', 'f', 'g', '\n', 'w', 'x', 'y', 'z', '\n'

after which a subsequent attempt to read will encounter the EOF
condition, which getc(stream) will represent by returning the special
EOF value (typically -1).

Suppose we edit the file with a "binary editor" and remove the last
line, but also remove the newline that comes after the first line.
Then getc() will return:

'a', 'b', 'c', 'd', 'e', 'f', 'g', EOF
Let's look at my code (int charInput, tmp;)

do
{
printf("\nWrite to result.txt (y/n)? ");
charInput = getchar();

do {
tmp = getchar();
} while(EOF != tmp && '\n' != tmp); // */

}
while (charInput != 'y' && charInput != 'n');
Here, charInput will get the 'a', leaving 'b' thorugh 'g' in the
stream. Then the loop using "tmp" will get the 'b', then 'c', then
'd', ..., then 'g', then EOF. Since EOF == EOF, the loop will stop
at this point, with tmp==EOF.

What happens if we replace the input file with one that contains the
character sequence '\n', 'y', '\n' (then EOF)?
I did a little debugging and it seems like charInput always contains the
first character I enter, while tmp always contains "10" which AFAIR is \n.
It is on most systems.
Shouldn't the while line be changed to: } while(EOF != tmp || '\n' !=
tmp);? I mean: tmp can't be EOF and \n at the same time, can it?
Indeed, it cannot be equal to both EOF (a negative integer) and '\n'
(a positive integer). What happens if you ask whether, for instance:

if (EOF != EOF || EOF != '\n')

?
I tried Ctrl+D on mac os x. Isn't that EOF?


It is set-able, but that is the default. However, depending on the
C library, you may sometimes have to type it more than once. The
C standard allows, but in C89 at least does not require, EOF to be
"sticky": if a stream encounters EOF, the C library can stop asking
the underlying OS for more input until you call clearerr() on the
stream. On the other hand, the C library can go ahead and keep
asking for more input anyway. Different systems do different things
here.
--
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.
Feb 19 '06 #34
Michael Mair wrote:
-snip-
No. But the loop has to stop if tmp either equals EOF or equals '\n',
that is, it runs as long as tmp equals neither.


Oh, yeah... The other thing also didn't work. Thanks...
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Feb 19 '06 #35
Chris Torek wrote:
-snip-
do
{
printf("\nWrite to result.txt (y/n)? ");
charInput = getchar();

do {
tmp = getchar();
} while(EOF != tmp && '\n' != tmp); // */

}
while (charInput != 'y' && charInput != 'n');

Here, charInput will get the 'a', leaving 'b' thorugh 'g' in the
stream. Then the loop using "tmp" will get the 'b', then 'c', then
'd', ..., then 'g', then EOF. Since EOF == EOF, the loop will stop
at this point, with tmp==EOF.

What happens if we replace the input file with one that contains the
character sequence '\n', 'y', '\n' (then EOF)?


Great explanation... And there we have a (small) bug... charInput will
be "\n" while "tmp" will be y. Therefore the program will never test the
y positive in the outer loop (the line: while (charInput != 'y' &&
charInput != 'n');)

Hmmm... I'm not so experienced here, so what would a good solution to
the program be? Perhaps adding (to the inner loop) if(tmp == 'y' || tmp
== 'n'), then do: charInput == tmp (untested)? Would that work?
I did a little debugging and it seems like charInput always contains the
first character I enter, while tmp always contains "10" which AFAIR is \n.

It is on most systems.

Shouldn't the while line be changed to: } while(EOF != tmp || '\n' !=
tmp);? I mean: tmp can't be EOF and \n at the same time, can it?

Indeed, it cannot be equal to both EOF (a negative integer) and '\n'
(a positive integer). What happens if you ask whether, for instance:

if (EOF != EOF || EOF != '\n')


Oh, yeah... You mean: "while" instead of "if", right (like in the
program)? It never asks me for input again... Must be because that
if-sentence is always true and therefore tmp = getchar() will run
forever... Your if-sentence will also run forever, I can see now because
either one of the two expressions will always be true - therefore the
whole thing is true...
I tried Ctrl+D on mac os x. Isn't that EOF?

It is set-able, but that is the default. However, depending on the


How to set it up in linux? Might be the same for mac os x.
C library, you may sometimes have to type it more than once. The
C standard allows, but in C89 at least does not require, EOF to be
"sticky": if a stream encounters EOF, the C library can stop asking
the underlying OS for more input until you call clearerr() on the
stream. On the other hand, the C library can go ahead and keep
asking for more input anyway. Different systems do different things
here.


Strange... Under xcode development tool ctrl+D doesn't work. But in a
terminal window, typing ctrl+D makes it go crazy like an infinite loop
writing: "Write to result.txt (y/n)? "

Is this code correct when typing ctrl+D = EOF I assume?

main() // can't remember if this syntax is correct
{
int charInput, tmp;
do
{
printf("\nWrite to result.txt (y/n)? ");
charInput = getchar();

do {
tmp = getchar();
} while(EOF != tmp && '\n' != tmp); // */

}
while (charInput != 'y' && charInput != 'n');

}

I wanted to copy/paste my own code but it has a lot of ^M in it and I
haven't figured out yet how to convert those line endings on
linux/unix/mac correct (wrote be the textedit application) so I just
inserted main(){ ... } to the code I previously posted.
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Feb 19 '06 #36
Chris Torek <no****@torek.net> writes:
[...]
In article <lh************@news.tdc.dk>
Martin Jørgensen <un*********@spam.jay.net> wrote:

[...]
I tried Ctrl+D on mac os x. Isn't that EOF?


It is set-able, but that is the default. However, depending on the
C library, you may sometimes have to type it more than once. The
C standard allows, but in C89 at least does not require, EOF to be
"sticky": if a stream encounters EOF, the C library can stop asking
the underlying OS for more input until you call clearerr() on the
stream. On the other hand, the C library can go ahead and keep
asking for more input anyway. Different systems do different things
here.


I'm going to jump in here and point out that the term EOF is being
used to refer to several different things. Control-D is not EOF;
Control-D might be (on some systems) the character that you enter to
trigger and end-of-file condition, which will then cause getchar() to
return the value EOF.

EOF is a macro, defined in <stdio.h>. It expands to a negative
integer value. getchar() returns that value to denote an end-of-file
or error condition. The way an end-of-file condition is triggered
varies from system to system and from file to file, and is outside the
scope of the C standard. If you're reading from a disk file, reaching
the end of the file commonly triggers the end-of-file condition; this
is a function of the size of the file, not of its contents (i.e.,
there's not necessarily a character that marks the end of the file).
If you're reading from a keyboard, typically some special character is
used by the system to trigger an end-of-file condition; this is
usually control-D on Unix-like systems and control-Z on DOS-like
systems. The character itself is not seen by the program, though
there may be a way to transmit that character directly. For example,
on Unix, if you type control-V control-D, your program will see a
control-D (ASCII code 4) character; this is *not* EOF.

--
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 19 '06 #37
"Martin Jørgensen" <un*********@spam.jay.net> wrote in message
news:jf************@news.tdc.dk...
main() // can't remember if this syntax is correct
int main(void)
{
int charInput, tmp;
do
{
printf("\nWrite to result.txt (y/n)? ");
charInput = getchar();
First character can be EOF or '\n', you should compare charInput to those
values and take desired action. Maybe you want to do it this way or maybe
not:

if (charInput==EOF)
break;

if (charInput=='\n')
continue;
do {
tmp = getchar();
} while(EOF != tmp && '\n' != tmp); // */
You will have to check why the previous while loop exited. That would be
because EOF or newline was encoutered. You should take action not to read
beyond EOF, the same way as above.
}
while (charInput != 'y' && charInput != 'n');


When you exit the above while loop, you have to determine why it exited.
Maybe you reached EOF before 'y'/'n' were typed.
Feb 19 '06 #38

"stathis gotsis" <st***********@hotmail.com> wrote in message
news:dt**********@ulysses.noc.ntua.gr...
"Martin Jørgensen" <un*********@spam.jay.net> wrote in message
news:jf************@news.tdc.dk...
main() // can't remember if this syntax is correct
int main(void)
{
int charInput, tmp;
do
{
printf("\nWrite to result.txt (y/n)? ");
charInput = getchar();


First character can be EOF or '\n', you should compare charInput to those
values and take desired action. Maybe you want to do it this way or maybe
not:

if (charInput==EOF)
break;


I thought feof(), not EOF, was the preferred method for ANSI C to check
end-of-file. Am I mistaken?
if (charInput=='\n')
continue;
do {
tmp = getchar();
} while(EOF != tmp && '\n' != tmp); // */


You will have to check why the previous while loop exited. That would be
because EOF or newline was encoutered. You should take action not to read
beyond EOF, the same way as above.
}
while (charInput != 'y' && charInput != 'n');


When you exit the above while loop, you have to determine why it exited.
Maybe you reached EOF before 'y'/'n' were typed.


Rod Pemberton
Feb 20 '06 #39
On 2006-02-19, Martin Jørgensen <un*********@spam.jay.net> wrote:
Chris Torek wrote:
-snip-
do
{
printf("\nWrite to result.txt (y/n)? ");
charInput = getchar();

do {
tmp = getchar();
} while(EOF != tmp && '\n' != tmp); // */

}
while (charInput != 'y' && charInput != 'n');

Here, charInput will get the 'a', leaving 'b' thorugh 'g' in the
stream. Then the loop using "tmp" will get the 'b', then 'c', then
'd', ..., then 'g', then EOF. Since EOF == EOF, the loop will stop
at this point, with tmp==EOF.

What happens if we replace the input file with one that contains the
character sequence '\n', 'y', '\n' (then EOF)?


Great explanation... And there we have a (small) bug... charInput will
be "\n" while "tmp" will be y. Therefore the program will never test the
y positive in the outer loop (the line: while (charInput != 'y' &&
charInput != 'n');)

Hmmm... I'm not so experienced here, so what would a good solution to
the program be? Perhaps adding (to the inner loop) if(tmp == 'y' || tmp
== 'n'), then do: charInput == tmp (untested)? Would that work?
I did a little debugging and it seems like charInput always contains the
first character I enter, while tmp always contains "10" which AFAIR is \n.

It is on most systems.

Shouldn't the while line be changed to: } while(EOF != tmp || '\n' !=
tmp);? I mean: tmp can't be EOF and \n at the same time, can it?

Indeed, it cannot be equal to both EOF (a negative integer) and '\n'
(a positive integer). What happens if you ask whether, for instance:

if (EOF != EOF || EOF != '\n')


Oh, yeah... You mean: "while" instead of "if", right (like in the
program)? It never asks me for input again... Must be because that
if-sentence is always true and therefore tmp = getchar() will run
forever... Your if-sentence will also run forever, I can see now because
either one of the two expressions will always be true - therefore the
whole thing is true...
I tried Ctrl+D on mac os x. Isn't that EOF?

It is set-able, but that is the default. However, depending on the


How to set it up in linux? Might be the same for mac os x.
C library, you may sometimes have to type it more than once. The
C standard allows, but in C89 at least does not require, EOF to be
"sticky": if a stream encounters EOF, the C library can stop asking
the underlying OS for more input until you call clearerr() on the
stream. On the other hand, the C library can go ahead and keep
asking for more input anyway. Different systems do different things
here.


Strange... Under xcode development tool ctrl+D doesn't work. But in a
terminal window, typing ctrl+D makes it go crazy like an infinite loop
writing: "Write to result.txt (y/n)? "


The most common reason for this is if you fail to check for an
end-of-file condition and break a loop. This is most commonly from using
scanf incorrectly, but the issue exists with many other functions.

For example, if you're re-prompting if the character input is not 'y' or
'n' - well, end-of-file is neither. If you're using scanf, it's nothing
at all. [the pointed-at object is not assigned to]
Feb 20 '06 #40
On 2006-02-19, Rod Pemberton <do*********@sorry.bitbucket.cmm> wrote:

"stathis gotsis" <st***********@hotmail.com> wrote in message
news:dt**********@ulysses.noc.ntua.gr...
"Martin Jørgensen" <un*********@spam.jay.net> wrote in message
news:jf************@news.tdc.dk...
> main() // can't remember if this syntax is correct


int main(void)
> {
> int charInput, tmp;
>
>
> do
> {
> printf("\nWrite to result.txt (y/n)? ");
> charInput = getchar();


First character can be EOF or '\n', you should compare charInput to those
values and take desired action. Maybe you want to do it this way or maybe
not:

if (charInput==EOF)
break;


I thought feof(), not EOF, was the preferred method for ANSI C to check
end-of-file. Am I mistaken?


Both are valid and well-defined in ANSI C. They have different
semantics, and EOF lends itself better to the most common idioms for
looping over input.
Feb 20 '06 #41
En news:43***************@yahoo.com, CBFalconer va escriure:
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1135.pdf>, which is
an ISO/IEC draft Technical Report.
Took a quick look, and I think it is ignoring real work going on
in the C world.


What do you mean?
- the dTR is ignoring part of the C world:
correct, but neither does it pretend to encompass it as a whole;
- the dTR is never applied anywhere:
this would be wrong;
- some points escaped to the committee:
I guess you are allowed to share your concerns ;-); however you
probably should check the previous comments done so far.

Glaringly obvious are missing references to strlcat and strlcpy
from FreeBSD,
The origin is more OpenBSD than FreeBSD, as far as I know.

You shoud read the rationale (N1147) before commenting in such a way.
Obviously strlcpy() and strlcat() were considered, and discarded (1.1.15,
6.7.1.3, 6.7.2.1).

which make much more sense than the proposals.


Perhaps. But given your first comment above, I am not sure you have a better
understanding of the objectives of the TR than the committee; as such, I am
not at ease to give you full credit at this point about the relative
sensitiveness of both proposals (please note I am not saying the committee
is full correct either.)
Another position could be to discard completely the proposed TR (and stay
with strlcpy()). Be sure you certainly will not be alone in such a position.
I even believe the majority will be in this position.

It is very different from the C Standard in this respect. Trying to
masquerade the TR as a new evolution of the C Standard is going the wrong
way (I think).
Thinking the future of the C language would be constrained to this TR is
even more wrong, and this is should be clear enough.
Antoine

Feb 20 '06 #42
stathis gotsis wrote:
"Martin Jørgensen" <un*********@spam.jay.net> wrote in message
news:jf************@news.tdc.dk...
main() // can't remember if this syntax is correct

int main(void)

{
int charInput, tmp;
Just a small thing: charInput should not be an array, right? getchar
doesn't overwrite anything in the address after charInput (at index[1]
or at charInput[2]) or something, right?
do
{
printf("\nWrite to result.txt (y/n)? ");
charInput = getchar();

First character can be EOF or '\n', you should compare charInput to those
values and take desired action. Maybe you want to do it this way or maybe
not:

if (charInput==EOF)
break;

if (charInput=='\n')
continue;

do {
tmp = getchar();
} while(EOF != tmp && '\n' != tmp); // */

You will have to check why the previous while loop exited. That would be
because EOF or newline was encoutered. You should take action not to read
beyond EOF, the same way as above.


I did just as you proposed. Looks fine to me...
}
while (charInput != 'y' && charInput != 'n');

When you exit the above while loop, you have to determine why it exited.
Maybe you reached EOF before 'y'/'n' were typed.


Yeah, you're right. I have to check for EOF here too, I guess. I assume
my program is pretty much bulletproof now, right?:

--------
#include <stdio.h>

int main(void)
{
int charInput, tmp;

do
{
printf("\nWrite to result.txt (y/n)? ");
charInput = getchar();
if (charInput==EOF)
break;
if (charInput=='\n')
continue;

do {
tmp = getchar();
} while(EOF != tmp && '\n' != tmp);

}
while (charInput != 'y' && charInput != 'n' && charInput != EOF);

printf("Thank you very much\n");
printf("You typed: %c\n", charInput);

return 0;
}

------
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Feb 20 '06 #43
Jordan Abel wrote:
-snip-
The most common reason for this is if you fail to check for an
end-of-file condition and break a loop. This is most commonly from using
scanf incorrectly, but the issue exists with many other functions.
Damn. You're right... See this output now:

../a.out

Write to result.txt (y/n)? a

Write to result.txt (y/n)? Thank you very much
You typed: ?

Interesting to me to see that it writes: "You typed: ?" as a response to
ctrl+D...
For example, if you're re-prompting if the character input is not 'y' or
'n' - well, end-of-file is neither. If you're using scanf, it's nothing
at all. [the pointed-at object is not assigned to]


Makes sense... Can you also explain why ctrl+d => "You typed: ?"
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Feb 20 '06 #44
Martin Jørgensen <un*********@spam.jay.net> writes:
stathis gotsis wrote:
"Martin Jørgensen" <un*********@spam.jay.net> wrote in message
news:jf************@news.tdc.dk...
main() // can't remember if this syntax is correct int main(void)
{
int charInput, tmp;


Just a small thing: charInput should not be an array, right? getchar
doesn't overwrite anything in the address after charInput (at index[1]
or at charInput[2]) or something, right?


getchar() doesn't overwrite anything; it just returns a value. If you
assign that value to a variable, there's no way it can overwrite
anything else.

[...]
#include <stdio.h>

int main(void)
{
int charInput, tmp;

do
{
printf("\nWrite to result.txt (y/n)? ");
charInput = getchar();
if (charInput==EOF)
break;
if (charInput=='\n')
continue;

do {
tmp = getchar();
} while(EOF != tmp && '\n' != tmp);

}
while (charInput != 'y' && charInput != 'n' && charInput != EOF);

printf("Thank you very much\n");
printf("You typed: %c\n", charInput);

return 0;
}


I haven't checked your program for correctness, but I have a style
comment. Some C programmers write variable tests as
if (42 == x)
to avoid the error of writing "=" rather than "=="; if you
inadvertently write
if (x = 42)
rather than
if (x == 42)
the compiler won't (necessarily) catch your error, but if you write
if (42 = x)
when you meant
if (42 == x)
the compiler will certainly complain.

Personally, I find the reversed form almost unbearably ugly (and not
particularly useful for "!=") , but I understand the rationale for
using it. In your program, you don't use it consistently; some tests
have the constant on the right, some have the constant on the left.
Consistency is your friend.

--
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 20 '06 #45
"Martin Jørgensen" <un*********@spam.jay.net> wrote in message
news:f2************@news.tdc.dk...
#include <stdio.h>

int main(void)
{
int charInput, tmp;

do
{
printf("\nWrite to result.txt (y/n)? ");
charInput = getchar();
if (charInput==EOF)
break;
if (charInput=='\n')
continue;

do {
tmp = getchar();
} while(EOF != tmp && '\n' != tmp);
[1]: Consider breaking the outer loop if tmp==EOF. You should not read the
input stream beyond EOF.
}
while (charInput != 'y' && charInput != 'n' && charInput != EOF);
charInput!=EOF is not a needed condition, as charInput cannot be equal to
EOF at this point. Consider: while (charInput != 'y' && charInput != 'n' &&
tmp!= EOF); which also includes [1].
printf("Thank you very much\n");
printf("You typed: %c\n", charInput);
Check if charInput equals EOF before typing it.
return 0;
}

Feb 21 '06 #46
"Martin Jørgensen" <un*********@spam.jay.net> wrote in message
news:va************@news.tdc.dk...
Jordan Abel wrote:
-snip-
The most common reason for this is if you fail to check for an
end-of-file condition and break a loop. This is most commonly from using
scanf incorrectly, but the issue exists with many other functions.


Damn. You're right... See this output now:

./a.out

Write to result.txt (y/n)? a

Write to result.txt (y/n)? Thank you very much
You typed: ?

Interesting to me to see that it writes: "You typed: ?" as a response to
ctrl+D...
For example, if you're re-prompting if the character input is not 'y' or
'n' - well, end-of-file is neither. If you're using scanf, it's nothing
at all. [the pointed-at object is not assigned to]


Makes sense... Can you also explain why ctrl+d => "You typed: ?"


You should not print EOF using the %c format specifier. Try %d instead.
Feb 21 '06 #47
stathis gotsis schrieb:
"Martin Jørgensen" <un*********@spam.jay.net> wrote in message
news:va************@news.tdc.dk...

<snip>
Makes sense... Can you also explain why ctrl+d => "You typed: ?"


You should not print EOF using the %c format specifier. Try %d instead.


.... because EOF is not a character but a condition indicator.

-Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Feb 21 '06 #48
Keith Thompson wrote:
-snip-
Personally, I find the reversed form almost unbearably ugly (and not
particularly useful for "!=") , but I understand the rationale for
using it. In your program, you don't use it consistently; some tests
have the constant on the right, some have the constant on the left.
Consistency is your friend.


Oh, thanks for the comment. I also find it a bit ugly and also wondered
why someone here in this group suggested it... But your explanation
answers this "reversed behaviour". I myself am however not very afraid
of missing an = sign in a logical test ( I think I'll quickly find out
anyway ), so I think I'll change the program so the variables always are
on the left-hand-side - That looks nicer IMO...
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Feb 21 '06 #49
stathis gotsis wrote:
-snip-
Makes sense... Can you also explain why ctrl+d => "You typed: ?"

You should not print EOF using the %c format specifier. Try %d instead.


No way...

Write to result.txt (y/n)? o

Write to result.txt (y/n)? u7

Write to result.txt (y/n)? n
Thank you very much
You typed: 110
Best regards / Med venlig hilsen
Martin Jørgensen

--
---------------------------------------------------------------------------
Home of Martin Jørgensen - http://www.martinjoergensen.dk
Feb 21 '06 #50

This discussion thread is closed

Replies have been disabled for this discussion.

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.