Ben Fitzgerald <> writes:
> On 27 Jun 2003 13:03:47 GMT, Dan Pop <> wrote:
> > In <> Ben Fitzgerald <> writes:
> >
> >>it works fine, of course, but I just got lint recently
> >>(actually splint on linux) and it complains:
> >>
> >> Assignment of int to char: x[i++] = c
> >>
> > No, it is not the correct and portable approach, but for another reason
> > than the lint complaint.
> >
> > You're assigning a value in the range 0..UCHAR_MAX to a variable that can
> > only represent the CHAR_MIN..CHAR_MAX range. Although this happens to
> > work most of the time on most of the platforms, it is not guaranteed by
> > the language to do the right thing.
> >
> > One idea would be declare x as array of unsigned char. But, if you want
> > to pass it to a library expecting a string, you have a problem, because
> > it expects a pointer to char as argument. So, the right solution is to
> > use a pointer to unsigned char when storing values into your array:
> >
> > int c, i = 0;
> > char x[20];
> > unsigned char *p = (unsigned char *)x;
> >
> > while((c = getchar()) != EOF && i < sizeof x - 1)
> > p[i++] = c;
>
> Okay, help me out here. If I assign c straight to x[i++]:
> x[i++] = c;
>
> I'm incorrect because c could contain a vaule greater than
> UCHAR_MAX, but x can only hold CHAR_MIN...CHAR_MAX
No, c will either hold a value from 0 to UCHAR_MAX (not greater), or
it will hold the value EOF.
> *But*, if you have (c = getchar()) != EOF) as a test in your
> while loop and getchar() "returns an unsigned char cast
> to an int, or EOF" (I got this quote from a linux man page!)
> then EOF cannot be assigned inside the loop thanks to the test
> so the former (unsigned char) will be assigned to x[i++]
Right, but that's the problem: assigning an unsigned char to a char
can overflow when char is a signed type.
If you are expecting that your file is made up entirely of textual
characters which are all representable in the char type, then you can
perform a check such as:
if (c > CHAR_MAX) {
/* c can't be represented as a regular char.
handle this as an error... */
}
Otherwise, if you want these bytes to be represented exactly, you
should follow Dan's advice.
>
> i.e.
> int c, i = 0;
> unsigned char x[20];
>
> while ((c=getchar()) != EOF && i < sizeof x - 1)
> x[i++] = c;
>
> Therefore, shouldn't array x simply be of type unsigned char!?
> I am agreeing with you in a roundabout way, just without the
> pointers, I think.
But, as Dan pointed out, you would then have difficulties using x with
the Standard Library's string manipulation facilities.
-Micah
|