I have a file in which each line contains hundreds of integers separated by tabs. I would like to read all of these into a 2 dimensional integer matrix, but I'm having trouble figuring out how to do it. I don't want to use "sscanf" with a bunch of "%d" symbols because Id have to have a ridiculously long string of those and because I don't know how many of them I will need in any particular line. I gather that I can make a loop and read them all in using a combination of "strtok", to cycle through the elements in the line, and "atoi" to convert the character strings to integers. Unfortunately, I'm having trouble getting this to work. (I'm quite new to C.) Could someone give me a short example of code that does this?
Thanks very much.
Eric -- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.
ef...@fhcrc.org wrote: > I have a file in which each line contains hundreds of integers > separated by tabs. I would like to read all of these into a 2 > dimensional integer matrix, but I'm having trouble figuring out how to > do it. I don't want to use "sscanf" with a bunch of "%d" symbols > because Id have to have a ridiculously long string of those and > because I don't know how many of them I will need in any particular > line. I gather that I can make a loop and read them all in using a > combination of "strtok", to cycle through the elements in the line, > and "atoi" to convert the character strings to integers. > Unfortunately, I'm having trouble getting this to work. (I'm quite new > to C.) Could someone give me a short example of code that does this?
atoi() is dangerous - if the file contains a digit string representing a value that is too large to be represented as an long int, the behavior of atoi() is undefined. If the string does not start out with a portion that could be interpreted as a correctly formated number, atoi() returns a 0, with no other indication that anything is wrong.
It's safer to use strtol(). If the string pointed by nptr represents a number that is two big to be represented as a long int, strtol(nptr, &endptr, 10) will set errno to ERANGE and return either LONG_MIN or LONG_MAX, depending upon the sign of the number. If nptr points at a string that cannot be interpreted as a correctly formated number, it returns 0. In either case, is sets endptr to be equal to nptr.
Using strtol() also eliminates the need for the strtok() call; if strtol(nptr, &endptr, 10) succeeds, it sets endptr to point after the end of the string that it processed.
#include <errno.h> #include <stdlib.h>
int fill_array( size_t max_elements; long array[], char buffer[] ){ char *nptr; char *endptr; int num;
nptr = buffer; errno = 0; for(num=0; *endptr && num<max_elements; num++) { array[num] = strtol(nptr, &endptr, 10); if(nptr == endptr) { if(errno == ERANGE) { /* The number was too big to be converted */ /* array[num] will be either LONG_MIN or LONG_MAX, * depending upon the sign of the number */ /* Handle error. */; } else { /* The string could not be interpreted as number */ /* array[num] will be 0. */ /* Handle error */; }
/* Unless your error handling changed either the * contents of the buffer or the location pointed * at by nptr, there is no point in making any more * calls to strtol(). Therefore, */ break; } else nptr = endptr; }
return num;
}
-- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.
Eric -- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.
On Wed, 3 Feb 2010 14:52:24 -0600 (CST), "ef...@fhcrc.org"
<ef...@fhcrc.org> wrote: >I have a file in which each line contains hundreds of integers >separated by tabs. I would like to read all of these into a 2 >dimensional integer matrix, but I'm having trouble figuring out how to >do it. I don't want to use "sscanf" with a bunch of "%d" symbols >because Id have to have a ridiculously long string of those and >because I don't know how many of them I will need in any particular >line. I gather that I can make a loop and read them all in using a >combination of "strtok", to cycle through the elements in the line, >and "atoi" to convert the character strings to integers. >Unfortunately, I'm having trouble getting this to work. (I'm quite new >to C.) Could someone give me a short example of code that does this?
If you don't know how many integers are in a line, how do you know the dimensions of the array?
Show the code that is not working and people will try to help you identify where your problems are. It would also be very useful if you tell us how you know the code is not doing what you want.
-- Remove del for email -- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.
On 2010-02-03, ef...@fhcrc.org <ef...@fhcrc.org> wrote:
> I have a file in which each line contains hundreds of integers > separated by tabs. I would like to read all of these into a 2 > dimensional integer matrix, but I'm having trouble figuring out how to > do it. I don't want to use "sscanf" with a bunch of "%d" symbols > because Id have to have a ridiculously long string of those and > because I don't know how many of them I will need in any particular > line. I gather that I can make a loop and read them all in using a > combination of "strtok", to cycle through the elements in the line, > and "atoi" to convert the character strings to integers. > Unfortunately, I'm having trouble getting this to work. (I'm quite new > to C.) Could someone give me a short example of code that does this?
what's wrong with fscanf()?
to read an int:
n=fscanrf( f, "%d", &intvar);
to skip spaces and other crud:
fscanf( f, "%*[^0-9\n]");
to check for end-of-line:
eol=fscanf( f, "%1[\n]" , &dummy_char);
--- news://freenews.netfront.net/ - complaints: n...@netfront.net --- -- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.
Jasen Betts wrote: > On 2010-02-03, ef...@fhcrc.org <ef...@fhcrc.org> wrote: >> I have a file in which each line contains hundreds of integers >> separated by tabs. I would like to read all of these into a 2 >> dimensional integer matrix, but I'm having trouble figuring out how to >> do it. I don't want to use "sscanf" with a bunch of "%d" symbols >> because Id have to have a ridiculously long string of those and >> because I don't know how many of them I will need in any particular >> line. I gather that I can make a loop and read them all in using a >> combination of "strtok", to cycle through the elements in the line, >> and "atoi" to convert the character strings to integers. >> Unfortunately, I'm having trouble getting this to work. (I'm quite new >> to C.) Could someone give me a short example of code that does this?
> what's wrong with fscanf()?
fscanf() treats newline characters the same as any other whitespace character. Human beings tend to treat newlines as special, except in text paragraphs. My experience has been that this discrepancy means that it is easy to write code based upon fscanf() that gets confused by corrupted inputs, with symptoms that are hard for human beings to debug.
Reading in a line at a time with fgets(), and then parsing it with sscanf(), is usually a better approach. It's easier to debug if something goes wrong. It may also make it easier to get the code right in the first place, though I'm not as sure about that. However, it does get clumsy when there's a large number of fields on the same line.
The other issue, for all members of the *scanf() family, is that section 7.19.6.2p10 says:
"... the result of the conversion is placed in the object pointed to by the first argument following the format argument that has not already received a conversion result. If this object does not have an appropriate type, or if the result of the conversion cannot be represented in the object, the behavior is undefined."
That's why it's safer to use the strto*() family of functions rather than relying upon the *scanf() family; if given valid arguments, their behavior is well-defined, regardless of the content of the string being processed. There's also footnote 251, which says:
"fscanf pushes back at most one input character onto the input stream. Therefore, some sequences that are acceptable to strtod, strtol, etc., are unacceptable to fscanf.".
I haven't bothered to figure out which kinds of sequences those are, but that's yet another reasons to favor strto*() of *scanf().
Note: I have not actually followed this advice very often - I don't write code that parses text very often, and most such code that I've written was written before I understood the issues raised above. Also, *scanf() format codes are much easier to use than strto*() calls. -- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.
If the input is a syntactically valid integer outside the range of int, the behavior is undefined.
-- Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" -- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.
On 3 Feb, 20:52, "ef...@fhcrc.org" <ef...@fhcrc.org> wrote:
> I have a file in which each line contains hundreds of integers > separated by tabs. I would like to read all of these into a 2 > dimensional integer matrix, but I'm having trouble figuring out how to > do it. I don't want to use "sscanf" with a bunch of "%d" symbols > because Id have to have a ridiculously long string of those and > because I don't know how many of them I will need in any particular > line. I gather that I can make a loop and read them all in using a > combination of "strtok", to cycle through the elements in the line, > and "atoi" to convert the character strings to integers. > Unfortunately, I'm having trouble getting this to work. (I'm quite new > to C.) Could someone give me a short example of code that does this?
As a programming principle - for C or another language - I'd suggest hiding the read of an integer in its own routine. Your code then splits into at least two parts. One works with integers doing whatever you want with then such as placing them in your matrix. The other handles the task of reading an integer. You call the second from the first each time you want another integer. See at least the first paragraph in
You would need to consider what the integer-read routine would do on such as
1. A suitable integer 2. A number that's too large 3. A signed integer 4. A non-space, non-digit character including a decimal point 5. The end of a line 6. The end of the file
Depending on your needs this gives two basic choices for the format of the call in C:
integer = integer_read(file)
or
status = integer_read(&integer, file)
The first is usable if there are some integer values that won't exist in the file. You can return these to indicate end of file and the like. The second allows you to return various status values separately from the integer.
Given the above structure you can then write the integer-read routine in any of a number of different ways - and can change the method later if desired. Apart from suggestions others have made consider using getc. It is a more fundamental call. You will learn more and have more flexibility that way.
James -- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.
James Kuyper wrote: > ... There's also footnote 251, which says:
> "fscanf pushes back at most one input character onto the input stream. > Therefore, some sequences that are acceptable to strtod, strtol, etc., > are unacceptable to fscanf.".
> I haven't bothered to figure out which kinds of sequences those are, but > that's yet another reasons to favor strto*() of *scanf().
Unverified, but exponential format integer input like 123E+X should make a difference. fscanf("%ld",...) reads up to X, finds that the input up to there is not a valid integer and can only return with an error. strtol() reads up to X and then backs up 2 characters to E, delivering 123 without error. -- Viele Grüße, Jens Schmidt -- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.
> "fscanf pushes back at most one input character onto the input stream. > Therefore, some sequences that are acceptable to strtod, strtol, etc., > are unacceptable to fscanf.".
> I haven't bothered to figure out which kinds of sequences those are...
Sequences where you need more than one character of lookahead to determine the actual valid part (if any). For example:
0xOOPS 1.23eek INCREDIBLE infinitesimal NABOB -- Larry Jones
Who, ME? Who?! Me?? WHO... Me?! Who, me??? -- Calvin -- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.
> Jasen Betts wrote: >> On 2010-02-03, ef...@fhcrc.org <ef...@fhcrc.org> wrote: >>> I have a file in which each line contains hundreds of integers >>> separated by tabs. I would like to read all of these into a 2 >>> dimensional integer matrix, but I'm having trouble figuring out how to >>> do it. I don't want to use "sscanf" with a bunch of "%d" symbols >>> because Id have to have a ridiculously long string of those and >>> because I don't know how many of them I will need in any particular >>> line. I gather that I can make a loop and read them all in using a >>> combination of "strtok", to cycle through the elements in the line, >>> and "atoi" to convert the character strings to integers. >>> Unfortunately, I'm having trouble getting this to work. (I'm quite new >>> to C.) Could someone give me a short example of code that does this?
>> what's wrong with fscanf()?
> fscanf() treats newline characters the same as any other whitespace > character.
only if you let it.
> Reading in a line at a time with fgets(), and then parsing it with > sscanf(), is usually a better approach.
fscanf doesn't always read a line.
> It's easier to debug if something goes wrong.
even with all that pointer arithmetic to re-join the lines that fscanf breaks?
> "... the result of the conversion is placed in the object pointed to by > the first argument following the format argument that has not already > received a conversion result. If this object does not have an > appropriate type, or if the result of the conversion cannot be > represented in the object, the behavior is undefined."
some compilers (gcc) can check for the first error, and fgets is succeptible to the second.
> That's why it's safer to use the strto*() family of functions rather > than relying upon the *scanf() family; if given valid arguments, their > behavior is well-defined, regardless of the content of the string being > processed. There's also footnote 251, which says: > "fscanf pushes back at most one input character onto the input stream. > Therefore, some sequences that are acceptable to strtod, strtol, etc., > are unacceptable to fscanf.".
> I haven't bothered to figure out which kinds of sequences those are, but > that's yet another reasons to favor strto*() of *scanf().
probably "INF" and "NAN" which don't "look" like numbers to scanf.
--- news://freenews.netfront.net/ - complaints: n...@netfront.net --- -- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.
> If the input is a syntactically valid integer outside the range of > int, the behavior is undefined.
undefined? I'd have expected unspecified.
--- news://freenews.netfront.net/ - complaints: n...@netfront.net --- -- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.
Jasen Betts wrote: > On 2010-02-05, James Kuyper <jameskuy...@verizon.net> wrote: >> Jasen Betts wrote: >>> On 2010-02-03, ef...@fhcrc.org <ef...@fhcrc.org> wrote: >>>> I have a file in which each line contains hundreds of integers >>>> separated by tabs. I would like to read all of these into a 2 >>>> dimensional integer matrix, but I'm having trouble figuring out how to >>>> do it. I don't want to use "sscanf" with a bunch of "%d" symbols >>>> because Id have to have a ridiculously long string of those and >>>> because I don't know how many of them I will need in any particular >>>> line. I gather that I can make a loop and read them all in using a >>>> combination of "strtok", to cycle through the elements in the line, >>>> and "atoi" to convert the character strings to integers. >>>> Unfortunately, I'm having trouble getting this to work. (I'm quite new >>>> to C.) Could someone give me a short example of code that does this? >>> what's wrong with fscanf()? >> fscanf() treats newline characters the same as any other whitespace >> character.
> only if you let it.
It's the default behavior, and not easily side-stepped. Using fgets() and sscanf() is much simpler.
>> Reading in a line at a time with fgets(), and then parsing it with >> sscanf(), is usually a better approach.
> fscanf doesn't always read a line.
Well, yes - that's why I said "usually". If you need to read only part of a line, fgets() is clearly the wrong approach; but for most cases where I might otherwise have used fscanf(), I did want to read and process one entire line at a time. Obviously, your experience might be quite different.
>> It's easier to debug if something goes wrong.
> even with all that pointer arithmetic to re-join the lines that fscanf breaks?
It depends upon what you're doing. If you do in fact need to re-join them, then fgets()/sscanf() is obviously not the right technique. That issue has never been relevant in my code, but I can see how it might be important for things like word processors.
>> "... the result of the conversion is placed in the object pointed to by >> the first argument following the format argument that has not already >> received a conversion result. If this object does not have an >> appropriate type, or if the result of the conversion cannot be >> represented in the object, the behavior is undefined."
> some compilers (gcc) can check for the first error, and fgets is succeptible > to the second.
sscanf() IS just as susceptible to that problem as fscanf(), which is why my very next paragraph introduced the idea of using the strto*() family of functions, which don't have that problem. However, fgets() has nothing to do with that problem, except in the sense of preparing the input for sscanf(). -- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.
Jasen Betts wrote: > On 2010-02-05, Keith Thompson <ks...@mib.org> wrote: >> Jasen Betts <ja...@xnet.co.nz> writes: >> [...] >>> what's wrong with fscanf()?
>>> to read an int:
>>> n=fscanrf( f, "%d", &intvar); >> [...]
>> If the input is a syntactically valid integer outside the range of >> int, the behavior is undefined.
> undefined? I'd have expected unspecified.
7.19.6.2p10: "... if the result of the conversion cannot be represented in the object, the behavior is undefined." -- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.
Jasen Betts <ja...@xnet.co.nz> writes: > On 2010-02-05, Keith Thompson <ks...@mib.org> wrote: >> Jasen Betts <ja...@xnet.co.nz> writes: >> [...] >>> what's wrong with fscanf()?
>>> to read an int:
>>> n=fscanrf( f, "%d", &intvar); >> [...]
>> If the input is a syntactically valid integer outside the range of >> int, the behavior is undefined.
> undefined? I'd have expected unspecified.
Yes, undefined. C99 7.19.6.2p10:
If this object does not have an appropriate type, or if the result of the conversion cannot be represented in the object, the behavior is undefined.
-- Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" -- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.
> Jasen Betts <ja...@xnet.co.nz> writes: >> On 2010-02-05, Keith Thompson <ks...@mib.org> wrote: >>> Jasen Betts <ja...@xnet.co.nz> writes: >>> [...] >>>> what's wrong with fscanf()?
>>>> to read an int:
>>>> n=fscanrf( f, "%d", &intvar); >>> [...]
>>> If the input is a syntactically valid integer outside the range of >>> int, the behavior is undefined.
>> undefined? I'd have expected unspecified.
> Yes, undefined. C99 7.19.6.2p10:
> If this object does not have an appropriate type, or if the result > of the conversion cannot be represented in the object, the > behavior is undefined.
According to sentence before that, it's safe if no assignment is done, (eg: "%*d").
How wierd!
--- news://freenews.netfront.net/ - complaints: n...@netfront.net --- -- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.
Jasen Betts <ja...@xnet.co.nz> writes: > On 2010-02-06, Keith Thompson <ks...@mib.org> wrote: >> Jasen Betts <ja...@xnet.co.nz> writes: >>> On 2010-02-05, Keith Thompson <ks...@mib.org> wrote: [...] >>>> If the input is a syntactically valid integer outside the range of >>>> int, the behavior is undefined.
>>> undefined? I'd have expected unspecified.
>> Yes, undefined. C99 7.19.6.2p10:
>> If this object does not have an appropriate type, or if the result >> of the conversion cannot be represented in the object, the >> behavior is undefined.
> According to sentence before that, it's safe if no assignment is done, > (eg: "%*d").
> How wierd!
It doesn't seem weird to me. It says "If this object ..."; in the case of "%*d", there is no relevant object.
It might require some extra work for some implementations to avoid Bad Things Happening for "%*d", perhaps a bit of special-case code that only parses the input without trying to convert to to an integer. Other implementations can just quietly ignore the overflow.
Still, I would have been happier if the behavior hadn't been left undefined. Implementations already have to be able to handle overflowing string-to-number conversions for strto*(); requiring some sort of reasonable behavior for *scanf() wouldn't have been too much of a burden.
Perhaps at the time the standard was being written, some implementations treated an overflowing integer as a failed conversion, and other stored some arbitrary value. Perhaps the authors of the standard decided not to force some implementations to change. It's not the decision I would have made. (I am, of course, speaking with 20+ years of hindsight.)
-- Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" -- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.
> Jasen Betts <ja...@xnet.co.nz> writes: >> On 2010-02-06, Keith Thompson <ks...@mib.org> wrote: >>> Jasen Betts <ja...@xnet.co.nz> writes: >>>> On 2010-02-05, Keith Thompson <ks...@mib.org> wrote: > [...] >>>>> If the input is a syntactically valid integer outside the range of >>>>> int, the behavior is undefined.
>>>> undefined? I'd have expected unspecified.
>>> Yes, undefined. C99 7.19.6.2p10:
>>> If this object does not have an appropriate type, or if the result >>> of the conversion cannot be represented in the object, the >>> behavior is undefined.
>> According to sentence before that, it's safe if no assignment is done, >> (eg: "%*d").
>> How wierd!
> It doesn't seem weird to me. It says "If this object ..."; in the > case of "%*d", there is no relevant object.
> It might require some extra work for some implementations to avoid > Bad Things Happening for "%*d", perhaps a bit of special-case > code that only parses the input without trying to convert to to an > integer. Other implementations can just quietly ignore the overflow.
> Still, I would have been happier if the behavior hadn't been > left undefined. Implementations already have to be able to handle > overflowing string-to-number conversions for strto*(); requiring > some sort of reasonable behavior for *scanf() wouldn't have been > too much of a burden.
> Perhaps at the time the standard was being written, some > implementations treated an overflowing integer as a failed > conversion, and other stored some arbitrary value. Perhaps the > authors of the standard decided not to force some implementations > to change. It's not the decision I would have made. (I am, of > course, speaking with 20+ years of hindsight.)
even then it would be implementation defined behavior
"undefined behavior" is no rules of behavior whatsoever... usually for cases where (to use real-world terms) you can corrupt the stack, heap, or other memory regions not involved in the expression.
// implementation defined behavior int foo(void) { int a ; return a;
}
// undefined behavior void bar(int i) { int *a; *a=i;
}
--- news://freenews.netfront.net/ - complaints: n...@netfront.net --- -- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.
Jasen Betts <ja...@xnet.co.nz> writes: > On 2010-02-08, Keith Thompson <ks...@mib.org> wrote: [...] >> Still, I would have been happier if the behavior hadn't been >> left undefined. Implementations already have to be able to handle >> overflowing string-to-number conversions for strto*(); requiring >> some sort of reasonable behavior for *scanf() wouldn't have been >> too much of a burden.
>> Perhaps at the time the standard was being written, some >> implementations treated an overflowing integer as a failed >> conversion, and other stored some arbitrary value. Perhaps the >> authors of the standard decided not to force some implementations >> to change. It's not the decision I would have made. (I am, of >> course, speaking with 20+ years of hindsight.)
> even then it would be implementation defined behavior
Not necessarily. The standard could define some specific behavior for sscanf("999999999999999999", "%d", &n); where 999999999999999999 > INT_MAX. Agreeing on what that specific behavior should be would be non-trivial.
> "undefined behavior" is no rules of behavior whatsoever... usually > for cases where (to use real-world terms) you can corrupt the stack, > heap, or other memory regions not involved in the expression.
> // implementation defined behavior > int foo(void) > { > int a ; > return a; > }
``a'' has an indeterminate value, which is either an unspecified value or a trap representation. If type int has trap representations, the behavior is undefined. If it doesn't, the value is unspecified, which means that it's a valid value but there are no requirements on what the value should be. In particular, it's not implementation defined; the implementation is not required to document what the value will be.
-- Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst> Nokia "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister" -- comp.lang.c.moderated - moderation address: c...@plethora.net -- you must have an appropriate newsgroups line in your header for your mail to be seen, or the newsgroup name in square brackets in the subject line. Sorry.