By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,852 Members | 955 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,852 IT Pros & Developers. It's quick & easy.

Some Newb Problem with "int", please help.

P: n/a
The problem professor gave us is:

Write a program which reads two integer values. If the first is less
than the second, print the message "up". If the second is less than
the first, print the message "down" If the numbers are equal, print
the message "equal" If there is an error reading the data, print a
message containing the word "Error" and perform exit( 0 );
And this is what I wrote:

main()
{
int x;
int y;

printf("Enter the first integer: ");
scanf("%d", &x);

printf("Enter the second integer: ");
scanf("%d", &y);

if (x > y)
{
printf("Up");
}
else
{
if (x < y)
{
printf("Down");
}
else
{
if (x = y)
{
printf("Equal");
}
else
{
printf("Error");
getch();
exit (0);
}
}
}
}

Works fine at first, but whenever I enter invalid characters such as
!, A, %, :, etc. It never asks me for the second integer and skip to
printf("Down");
Can anyone be kind enough to explain to me why that happened?
Nov 14 '05 #1
Share this Question
Share on Google+
24 Replies


P: n/a
On 2004-09-20, Apotheosis <he*************@yahoo.com> wrote:
[ code using scanf snipped ]

Works fine at first, but whenever I enter invalid characters such as
!, A, %, :, etc. It never asks me for the second integer and skip to
printf("Down");
Can anyone be kind enough to explain to me why that happened?


Don't use scanf. Read the answer to question 12.20 in the C-faq
to find out why.

http://www.eskimo.com/~scs/C-faq/top.html

-- James

Dude, you're reading the C-faq!
Nov 14 '05 #2

P: n/a
Apotheosis wrote:

The problem professor gave us is:

Write a program which reads two integer values. If the first is less
than the second, print the message "up". If the second is less than
the first, print the message "down" If the numbers are equal, print
the message "equal" If there is an error reading the data, print a
message containing the word "Error" and perform exit( 0 );

And this is what I wrote:

main()
{
int x;
int y;

printf("Enter the first integer: ");
scanf("%d", &x);

printf("Enter the second integer: ");
scanf("%d", &y);
.... snip ...
Works fine at first, but whenever I enter invalid characters such as
!, A, %, :, etc. It never asks me for the second integer and skip to
printf("Down");
Can anyone be kind enough to explain to me why that happened?


Basically you have failed to detect the errors resulting from the
scanf calls. Those are both returning a single value, so they
should be of the form:

if (1 != scanf("%d", &x)) erroraction();
else {
....
}

Never use scanf without checking the return value. Also, main
returns an int. Say so. You should be using:

int main(void)
{
....
return 0;
}

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #3

P: n/a
Apotheosis <he*************@yahoo.com> scribbled the following:
The problem professor gave us is: Write a program which reads two integer values. If the first is less
than the second, print the message "up". If the second is less than
the first, print the message "down" If the numbers are equal, print
the message "equal" If there is an error reading the data, print a
message containing the word "Error" and perform exit( 0 ); And this is what I wrote:
main()
{
int x;
int y; printf("Enter the first integer: ");
scanf("%d", &x); printf("Enter the second integer: ");
scanf("%d", &y); if (x > y)
{
printf("Up");
}
else
{
if (x < y)
{
printf("Down");
}
else
{
if (x = y)
Everyone other failed to spot this. You want == here, not =. = first
assigns y's value to x and then tests if x's value is anything other
than 0. This means that if execution gets this far, any value entered
to y at all, as far as it isn't 0, will print "Equal" regardless of
x's value. Because you already tested for x > y and x < y, this would
otherwise not matter, but it's going to break if you type 0 for both
x and y. In this case your program won't print anything at all.
{
printf("Equal");
}
else
{
printf("Error");
getch();
exit (0);
}
}
}
}

Works fine at first, but whenever I enter invalid characters such as
!, A, %, :, etc. It never asks me for the second integer and skip to
printf("Down");
Can anyone be kind enough to explain to me why that happened?


--
/-- Joona Palaste (pa*****@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"I wish someone we knew would die so we could leave them flowers."
- A 6-year-old girl, upon seeing flowers in a cemetery
Nov 14 '05 #4

P: n/a
James Hu wrote:

On 2004-09-20, Apotheosis <he*************@yahoo.com> wrote:

[ code using scanf snipped ]


Works fine at first, but whenever I enter invalid characters such as
!, A, %, :, etc. It never asks me for the second integer and skip to
printf("Down");
Can anyone be kind enough to explain to me why that happened?


Don't use scanf. Read the answer to question 12.20 in the C-faq
to find out why.


I disagree.

/* BEGIN new.c */

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <ctype.h>

#define LENGTH 100
#define str(x) # x
#define xstr(x) str(x)
#define VSIZE (sizeof variables / sizeof *variables)

int main(void)
{
int x, y, n, rc;
long temp;
char array[LENGTH + 1], *nptr;
struct V {
int *address;
char *string;
} variables[]= {{&x, "first"}, {&y, "second"}};

for (n = 0; VSIZE > n; ++n) {
printf("Enter the %s integer: ", variables[n].string);
fflush(stdout);
rc = scanf("%" xstr(LENGTH) "[^\n]%*[^\n]", array);
if (!feof(stdin)) {
getchar();
}
if (rc != 1) {
puts("Error");
exit(0);
}
nptr = array;
while (isspace(*nptr)) {
++nptr;
}
if (*nptr == '+' || *nptr == '-') {
++nptr;
}
if (!isdigit(*nptr)) {
puts("Error_2");
exit(0);
}
errno = 0;
temp = strtol(array, NULL, 10);
if (errno != 0 || INT_MIN > temp || temp > INT_MAX) {
puts("Error_3");
exit(0);
}
*variables[n].address = (int)temp;
}
if (y > x) {
puts("Up");
} else {
if (x > y) {
puts("Down");
} else {
puts("Equal");
}
}
return 0;
}

/* END new.c */
--
pete
Nov 14 '05 #5

P: n/a
pete <pf*****@mindspring.com> writes:

rc = scanf("%" xstr(LENGTH) "[^\n]%*[^\n]", array);


For portability reasons a propper #define for the linebreak would be
IMHO fine.

Kind regards,
Nicolas
--
| Nicolas Pavlidis | Elvis Presly: |\ |__ |
| Student of SE & KM | "Into the goto" | \|__| |
| pa****@sbox.tugraz.at | ICQ #320057056 | |
|-------------------University of Technology, Graz----------------|
Nov 14 '05 #6

P: n/a
Apotheosis wrote:
The problem professor gave us is:

Write a program which reads two integer values. If the first is less
than the second, print the message "up". If the second is less than
the first, print the message "down" If the numbers are equal, print
the message "equal" If there is an error reading the data, print a
message containing the word "Error" and perform exit( 0 );
And this is what I wrote:

main()
{
int x;
int y;

printf("Enter the first integer: ");
scanf("%d", &x);

printf("Enter the second integer: ");
scanf("%d", &y);

if (x > y)
{
printf("Up");
}
else
{
if (x < y)
{
printf("Down");
}
else
{
if (x = y) here you should replace for x == y {
printf("Equal");
}
else
{
printf("Error");
getch();
exit (0);
}
}
}
}

Works fine at first, but whenever I enter invalid characters such as
!, A, %, :, etc. It never asks me for the second integer and skip to
printf("Down");
Can anyone be kind enough to explain to me why that happened?

--
Felipe Magno de Almeida
UIN: 2113442
email: felipe.almeida@ic unicamp br, felipe.m.almeida@gmail com
I am a C, modern C++, MFC, ODBC, Windows Services, MAPI developer
from synergy, and Computer Science student from State
University of Campinas(UNICAMP).
To know more about:
Unicamp: http://www.ic.unicamp.br
Synergy: http://www.synergy.com.br
current work: http://www.mintercept.com
Nov 14 '05 #7

P: n/a
Apotheosis <he*************@yahoo.com> spoke thus:

Your indentation is suboptimal, to put it mildly.
main()
main() returns int. You should say so, and must do so under C99.
else
{
if (x = y)
{
printf("Equal");
}
else
{
printf("Error");
getch();
exit (0);
}
}
}
You are missing a return statement; you must explicitly return an
integer under C89. Notice that your call to exit() does not always
occur.
}


--
Christopher Benson-Manica | I *should* know what I'm talking about - if I
ataru(at)cyberspace.org | don't, I need to know. Flames welcome.

Nov 14 '05 #8

P: n/a
he*************@yahoo.com (Apotheosis) writes:
The problem professor gave us is:

Write a program which reads two integer values. If the first is less
than the second, print the message "up". If the second is less than
the first, print the message "down" If the numbers are equal, print
the message "equal" If there is an error reading the data, print a
message containing the word "Error" and perform exit( 0 );
And this is what I wrote:

main()
{
int x;
int y;

printf("Enter the first integer: ");
scanf("%d", &x);

printf("Enter the second integer: ");
scanf("%d", &y);
[ rest of code snipped ]
}
}

Works fine at first, but whenever I enter invalid characters such as
!, A, %, :, etc. It never asks me for the second integer and skip to
printf("Down");
Can anyone be kind enough to explain to me why that happened?


No, but perhaps if you can answer these questions you might figure it
out:

1) what does scanf() do if the input doesn't match the requested
conversion?

2) does scanf have a return value? If so, what is it, and how might
you use that to help you with this problem?

--
Remove -42 for email
Nov 14 '05 #9

P: n/a
Nicolas Pavlidis wrote:

pete <pf*****@mindspring.com> writes:
rc = scanf("%" xstr(LENGTH) "[^\n]%*[^\n]", array);


For portability reasons a propper #define for the linebreak would be
IMHO fine.


I don't understand what you mean.
Is there something there which is not portable?
What linebreak?

--
pete
Nov 14 '05 #10

P: n/a
pete wrote:
struct V {
int *address;
char *string;
} variables[]= {{&x, "first"}, {&y, "second"}};


That should be

struct V {
char *string;
int *address;
} variable[]= {{"first"}, {"second"}};

variable[0].address = &x;
variable[1].address = &y;

instead, since x and y are automatic variables.

--
pete
Nov 14 '05 #11

P: n/a
pete <pf*****@mindspring.com> writes:
Nicolas Pavlidis wrote:

pete <pf*****@mindspring.com> writes:
rc = scanf("%" xstr(LENGTH) "[^\n]%*[^\n]", array);


For portability reasons a propper #define for the linebreak would be
IMHO fine.


I don't understand what you mean.
Is there something there which is not portable?
What linebreak?


I ment the '\n' character. AFAIK Windows for example breaks lines with a
sequence carriage return + line feed, but maybe this has changed.

Kind regards,
Nicolas
--
| Nicolas Pavlidis | Elvis Presly: |\ |__ |
| Student of SE & KM | "Into the goto" | \|__| |
| pa****@sbox.tugraz.at | ICQ #320057056 | |
|-------------------University of Technology, Graz----------------|
Nov 14 '05 #12

P: n/a
Nicolas Pavlidis wrote:

pete <pf*****@mindspring.com> writes:
Nicolas Pavlidis wrote:

pete <pf*****@mindspring.com> writes:

> rc = scanf("%" xstr(LENGTH) "[^\n]%*[^\n]", array);

For portability reasons
a propper #define for the linebreak would be IMHO fine.


I don't understand what you mean.
Is there something there which is not portable?
What linebreak?


I ment the '\n' character.
AFAIK Windows for example breaks lines with a
sequence carriage return + line feed, but maybe this has changed.


I don't know in what context, what Window does, matters.

"there need not be a one-to-one correspondence between the
characters in a stream and those in the external representation"

C defines a stream line as ending in newline character.

N869
7.19.2 Streams
[#2] A text stream is an ordered sequence of characters
composed into lines, each line consisting of zero or more
characters plus a terminating new-line character. Whether
the last line requires a terminating new-line character is
implementation-defined. Characters may have to be added,
altered, or deleted on input and output to conform to
differing conventions for representing text in the host
environment. Thus, there need not be a one-to-one
correspondence between the characters in a stream and those
in the external representation.

Try this on a Windows box and see if the code is broken:

/* BEGIN new.c */

#include <stdio.h>
#include <stdlib.h>

#define LENGTH 65
#define str(x) # x
#define xstr(x) str(x)

int main(void)
{
int rc;
char string[LENGTH + 1];

fputs("Enter a string with spaces:", stdout);
fflush(stdout);
rc = scanf("%" xstr(LENGTH) "[^\n]%*[^\n]", string);
if (!feof(stdin)) {
getchar();
}
while (rc == 1) {
printf("Your string is:%s\n\n"
"Hit Enter key to end,\n or enter "
"another string to continue:", string);
fflush(stdout);
rc = scanf("%" xstr(LENGTH) "[^\n]%*[^\n]", string);
if (!feof(stdin)) {
getchar();
}
}
return 0;
}

/* END new.c */

--
pete
Nov 14 '05 #13

P: n/a
pete <pf*****@mindspring.com> writes:
"there need not be a one-to-one correspondence between the
characters in a stream and those in the external representation"

C defines a stream line as ending in newline character.


Ok, sorry.

Kind regards,
Nicolas

--
| Nicolas Pavlidis | Elvis Presly: |\ |__ |
| Student of SE & KM | "Into the goto" | \|__| |
| pa****@sbox.tugraz.at | ICQ #320057056 | |
|-------------------University of Technology, Graz----------------|
Nov 14 '05 #14

P: n/a

On Tue, 21 Sep 2004, Nicolas Pavlidis wrote:

pete <pf*****@mindspring.com> writes:
Nicolas Pavlidis wrote:
pete <pf*****@mindspring.com> writes:

rc = scanf("%" xstr(LENGTH) "[^\n]%*[^\n]", array);

For portability reasons a [proper] #define for the linebreak would
be IMHO fine.


I don't understand what you mean.
Is there something there which is not portable?
What linebreak?


I [meant] the '\n' character. AFAIK Windows for example breaks
lines with a sequence carriage return + line feed, but maybe
this has changed.


It has not. But it's not relevant to Windows programming, as someone
has already explained, because all decent DOS/Windows implementations
translate the two bytes 0D.0A to '\n' (for text streams) long before
the user's program ever sees them. So pete's code behaves perfectly
correctly on Windows systems, as well as on *nix.

There may be problems (and usually are, IME), however, when you
compile pete's code on a Unix or Linux implementation and then try to
feed it a text file generated on a DOS or Windows system. Unix
implementations tend not to understand 0D.0A, and /will/ pass the
extra byte along to the user's program (usually as '\r'). I don't
think the reverse is generally true: I think most Windows compilers
do understand that 0A without 0D is still '\n'.

So if you want your program to be as portably user-friendly as possible,
you ought to consider handling '\r\n' (and its Mac analogue '\r')
gracefully. But that's not a situation where a #define would help,
AFAIK. One really needs to make some fundamental design decisions to
support '\r\n' sensibly, and IMHO 'scanf' doesn't mix well with those
decisions.

HTH,
-Arthur
Nov 14 '05 #15

P: n/a
Arthur J. O'Dwyer wrote:

On Tue, 21 Sep 2004, Nicolas Pavlidis wrote:

pete <pf*****@mindspring.com> writes:
Nicolas Pavlidis wrote:
pete <pf*****@mindspring.com> writes:

> rc = scanf("%" xstr(LENGTH) "[^\n]%*[^\n]", array);
So if you want your program to be as portably user-friendly as
possible, you ought to consider handling '\r\n'
(and its Mac analogue '\r') gracefully.


I don't know about the Mac analogue case, but the scanf call above
with a \r\n terminated line, would still get you a string.
Parsing the string, is a job for another part of the code.

--
pete
Nov 14 '05 #16

P: n/a
In <Pi***********************************@unix42.andr ew.cmu.edu> "Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> writes:

There may be problems (and usually are, IME), however, when you
compile pete's code on a Unix or Linux implementation and then try to
feed it a text file generated on a DOS or Windows system.


You're invoking undefined behaviour in this case: you're opening in text
mode a file which is not a text file (on the platform opening it). The
things are even more obvious if the text file was generated on a VMS
system or some typical mainframe OS, because the differences are far more
impressive (each line is a record in the file and has no terminating
character(s)).

This is why text files must be properly *imported* on the system that
has to process them. Once this is done, the code can safely assume that
each line of text is \n terminated.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Currently looking for a job in the European Union
Nov 14 '05 #17

P: n/a
"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote:
On Tue, 21 Sep 2004, Nicolas Pavlidis wrote:

I [meant] the '\n' character. AFAIK Windows for example breaks
lines with a sequence carriage return + line feed, but maybe
this has changed.
It has not. But it's not relevant to Windows programming, as someone
has already explained, because all decent DOS/Windows implementations
translate the two bytes 0D.0A to '\n' (for text streams) long before
the user's program ever sees them.


Not just all decent implementations, _any_ implementation which is a C
implementation at all. The Standard requires it.
There may be problems (and usually are, IME), however, when you
compile pete's code on a Unix or Linux implementation and then try to
feed it a text file generated on a DOS or Windows system.


Possibly, but if this is something you need to do often you probably
have a proper file tranfer program which will do the translation for
you. (And if not, it's reasonably simple to write.)

Richard
Nov 14 '05 #18

P: n/a

On Wed, 22 Sep 2004, Dan Pop wrote:

"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> writes:
There may be problems (and usually are, IME), however, when you
compile pete's code on a Unix or Linux implementation and then try to
feed it a text file generated on a DOS or Windows system.


You're invoking undefined behaviour in this case: you're opening in text
mode a file which is not a text file (on the platform opening it).


True. That doesn't mean we should never try to do something reasonable
with it, though. (I'm not saying one should /always/ catch weird
newlines, but for programs that need maximum robustness and
user-friendliness I do think it's one of the first things to do.)

-Arthur
Nov 14 '05 #19

P: n/a

On Wed, 22 Sep 2004, Richard Bos wrote:

"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote:
On Tue, 21 Sep 2004, Nicolas Pavlidis wrote:

I [meant] the '\n' character. AFAIK Windows for example breaks
lines with a sequence carriage return + line feed, but maybe
this has changed.


It has not. But it's not relevant to Windows programming, as someone
has already explained, because all decent DOS/Windows implementations
translate the two bytes 0D.0A to '\n' (for text streams) long before
the user's program ever sees them.


Not just all decent implementations, _any_ implementation which is a C
implementation at all. The Standard requires it.


Nitpick: No, it doesn't. The Standard only requires that the
implementation translate /newlines/ to '\n' before the user code sees
them. If 0D.0A isn't a "newline" on the DS9000, then it doesn't have
to translate it. Replace "DS9000" by "brain-dead Windows implementation,
perhaps a naive GCC port," and you get exactly what I said.
There may be problems (and usually are, IME), however, when you
compile pete's code on a Unix or Linux implementation and then try to
feed it a text file generated on a DOS or Windows system.


Possibly, but if this is something you need to do often you probably
have a proper file tranfer program which will do the translation for
you. (And if not, it's reasonably simple to write.)


Certainly. But can you ensure that all your potential users have
such a program, or can write one; and that they all know how and when
to use it; and that they always remember to use it? </rhetorical>

-Arthur

Nov 14 '05 #20

P: n/a
In <Pi***********************************@unix45.andr ew.cmu.edu> "Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> writes:

On Wed, 22 Sep 2004, Dan Pop wrote:

"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> writes:
There may be problems (and usually are, IME), however, when you
compile pete's code on a Unix or Linux implementation and then try to
feed it a text file generated on a DOS or Windows system.
You're invoking undefined behaviour in this case: you're opening in text
mode a file which is not a text file (on the platform opening it).


True. That doesn't mean we should never try to do something reasonable
with it, though.


How can you do *anything* reasonable once undefined behaviour has been
invoked (by opening the file in the wrong mode)?
(I'm not saying one should /always/ catch weird
newlines, but for programs that need maximum robustness and
user-friendliness I do think it's one of the first things to do.)


As I already said in the text you've snipped, it is the user's job to
properly import the text file on the system he wants to process it. This
way, there is no undefined behaviour and the program need not try to do a
job it cannot be reliably done.

Last time I checked, file transfer protocols had a text mode that did
the right thing when dealing with text files, including character set
conversions. Furthermore, utilities for converting one text file format
to another are widely available (even a green newbie should be able to
convert between Unix, Windows and MacOS formats). Such a program has
the advantage that it knows what to expect as input format, it doesn't
have to resort to wild guessing.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Currently looking for a job in the European Union
Nov 14 '05 #21

P: n/a
"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote:

On Wed, 22 Sep 2004, Richard Bos wrote:

"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote:
It has not. But it's not relevant to Windows programming, as someone
has already explained, because all decent DOS/Windows implementations
translate the two bytes 0D.0A to '\n' (for text streams) long before
the user's program ever sees them.
Not just all decent implementations, _any_ implementation which is a C
implementation at all. The Standard requires it.


Nitpick: No, it doesn't. The Standard only requires that the
implementation translate /newlines/ to '\n' before the user code sees
them. If 0D.0A isn't a "newline" on the DS9000, then it doesn't have
to translate it.


If the DS9000 uses MS-DOS or Windows, 0D0A _is_ a newline there. If it
doesn't, then it has no bearing on "decent DOS/Windows implementations".
Replace "DS9000" by "brain-dead Windows implementation,
perhaps a naive GCC port," and you get exactly what I said.


Such a naive GCC port, working on native files in an MS-DOS or Windows
environment, would IMO not be conforming.
There may be problems (and usually are, IME), however, when you
compile pete's code on a Unix or Linux implementation and then try to
feed it a text file generated on a DOS or Windows system.


Possibly, but if this is something you need to do often you probably
have a proper file tranfer program which will do the translation for
you. (And if not, it's reasonably simple to write.)


Certainly. But can you ensure that all your potential users have
such a program, or can write one; and that they all know how and when
to use it; and that they always remember to use it? </rhetorical>


No; but then it's _their_ problem, not yours :-)

Richard
Nov 14 '05 #22

P: n/a

On Thu, 23 Sep 2004, Richard Bos wrote:

"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote:
On Wed, 22 Sep 2004, Richard Bos wrote:
"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote:
all decent DOS/Windows implementations
translate the two bytes 0D.0A to '\n'

Not just all decent implementations, _any_ implementation which is a C
implementation at all. The Standard requires it.


Nitpick: No, it doesn't. The Standard only requires that the
implementation translate /newlines/ to '\n' before the user code sees
them. If 0D.0A isn't a "newline" on the DS9000, then it doesn't have
to translate it.


If the DS9000 uses MS-DOS or Windows, 0D0A _is_ a newline there. If it
doesn't, then it has no bearing on "decent DOS/Windows implementations".


IMO the sequence 0D.0A is /only/ a "newline" if the implementation
defines it to be. (In other words, it's a QoI issue, not a conformance
issue.) Of course, I haven't got any C&V to back that up.
Replace "DS9000" by "brain-dead Windows implementation,
perhaps a naive GCC port," and you get exactly what I said.


Such a naive GCC port, working on native files in an MS-DOS or Windows
environment, would IMO not be conforming.


But processing the exact same files on a Linux system, it would be?
I don't think that's a very consistent interpretation, but I guess YMMV.
:)

Possibly, but if this is something you need to do often you probably
have a proper file tranfer program which will do the translation for
you. (And if not, it's reasonably simple to write.)


Certainly. But can you ensure that all your potential users have
such a program, or can write one; and that they all know how and when
to use it; and that they always remember to use it? </rhetorical>


No; but then it's _their_ problem, not yours :-)


Well, isn't part of user-friendliness to reduce the number of problems
your users are having? ;-)

-Arthur
Nov 14 '05 #23

P: n/a
[On \r\n as found on DOS-based systems, vs \r only as found on old Mac
systems, vs \n only as found on Unix-based systems including new Mac
systems...]

In article <news:ci**********@sunnews.cern.ch> Dan Pop <Da*****@cern.ch> wrote:
This is why text files must be properly *imported* on the system that
has to process them. Once this is done, the code can safely assume that
each line of text is \n terminated.


I agree, and I think at least one person provided another example
(VMS records) where no attempt to match any {\r, \n} clustering-sequence
would do the trick (because some VMS records are counted-byte-strings,
where you get an optional line number, a 16-bit byte-count, and then
the bytes making up the line, with no \r nor \n anywhere in sight).

An even more extreme example, which I hope will show that "import
text file" really *is* a Special Operation that *must* be done at
the point the text file is imported, occurs when transferring files
from some IBM mainframes. These machines use EBCDIC "code pages"
to determine which character code represents which character; but
all "text" code pages share a number of useful "text characters",
such as using 0xf0 through 0xf9 to store the characters '0' through
'9' respectively.

If an EBCDIC-coded file is not "imported" when moved to an ASCII-based
system, no amount of newline-fiddling will ever make it look like
anything other than gibberish. A VMS "record-oriented" file will
at least seem to have each line as a string of ASCII within it.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #24

P: n/a
Arthur J. O'Dwyer <aj*@nospam.andrew.cmu.edu> wrote:
On Wed, 22 Sep 2004, Dan Pop wrote:

"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> writes:
There may be problems (and usually are, IME), however, when you
compile pete's code on a Unix or Linux implementation and then try to
feed it a text file generated on a DOS or Windows system.
You're invoking undefined behaviour in this case: you're opening in text
mode a file which is not a text file (on the platform opening it).

True. That doesn't mean we should never try to do something reasonable
with it, though. (I'm not saying one should /always/ catch weird
newlines, but for programs that need maximum robustness and
user-friendliness I do think it's one of the first things to do.)


How can you do something reasonable after invoking undefined behavior?

If your file is not formatted to be a text file on the system you are on
then, by definition, it is not a text file and you should not be treating
it as such. On the other hand, if you are absolutely certain of the exact
format variations of the files that you are going to be working with, then
you can attempt to detect and correctly handle these formats in binary mode.

--
Alex Monjushko (mo*******@hotmail.com)
Nov 14 '05 #25

This discussion thread is closed

Replies have been disabled for this discussion.