EOF, getchar() and preprocessor portability issues (Re: O 
Author Message
 EOF, getchar() and preprocessor portability issues (Re: O


>My question is: 1. How do I detect (using preprocessor
>statements that they (instructor, assistant etc..))
>use 1. DOS, 2. DOS and Borland, 2. DOS and Symantec.
>3. Mac CodeWarrior. Do these platforms have some special
>keywords that my program can detect?

Almost certainly! :-) (but what they all are I couldn't say)

>And another question regarding EOF. I wrote a custom
>getchar()-based function for word input, comments were
>added while I was posting the article:

>        ushort i = 0;      /* typedef'ed as unsigned short */

Better to make that int. int generally corresponds to the most efficient
word size on a particular platform.

>        while (i < max)
>        {
>                arr[i] = getchar();

See below.

>                if (i == max)  /* check if we are within array boundaries */
>                {
>                        fprintf(stderr, "limit of %hd characters reached\n",
>                        MAX_LEN);                             break;

Does MAX_LEN really have type signed short?

>                }
>                if (arr[i] == EOF || arr == "")

You're comparing pointer values here in the 2nd part. You haven't yet created
a string in arr (by terminating it with a null character) so strcmp() isn't
any good either. You could write arr[0] == '\0' but is that really what
you want - it isn't an indication here of end-of-file.

>                {
>                        fprintf(stderr, "\nEOF detected, exiting..\n");
>                        exit (0);
>                }
>                if (arr[i] == '\n' || arr[i] == '\t' ||
>                arr[i] == ' ' || (!isalnum(arr[i])))
>                {
>                        arr[i] = '\0';                       /* end of word */
>                        break;
>                }
>                ++i;
>        }       /* more error chacking is done by the caller */
>#ifdef DEBUG
>        printf("DEBUG: Length of \"%s\" is %d\n", arr, i);
>        return i;

>Have you noticed that my getchar is putting characters into
>a char array and nevertheless I am able to intercept EOF?

This is entirely possible if your platform makes plain char a signed type.
ANSI C allows it to be an unsigned type and it is on some implementations.
The correct approach is to test the value against EOF before converting it
to char.

>However, I've heard that may not work on certain implementations
>and getchar should put input characters into an int array.

No you don't want an int array, just do the test before converting to
char, e.g.


        while (i < max)
                int ch = getchar();

                if (ch == EOF)
                        fprintf(stderr, "\nEOF detected, exiting..\n");
                        exit (0);

                arr[i] = ch;


Since you have ch available you might also now use it for the other tests
you do, since it is in precisely the right form for thing like isalnum()
(i.e. and unsigned char value converted to int, or EOF, although that
last case has already been filtered out).

>Will the program work the same way under DOS and Borland?
>If not what should I do? Take getchar input and put it into
>a temporary int variable, check for EOF and then assign it
>to arr[i]? My compiler will complain about casting. Is
>there any danger in casting it like:

>int temp;

>temp = getchar();
>if (temp != EOF)
>        arr[i] = (char)temp;

You can use the cast if you want to - it makes no difference.

>The problem is I *must* use a char array, it is predefined
>in the assignment.

You should anyway.

>Should I take a risk in hope it'll work
>on DOS and Mac?

Do it as above and it should work fine.



Fri, 08 Oct 1999 03:00:00 GMT  
 EOF, getchar() and preprocessor portability issues (Re: O


>how about:

>arr[i] = getchar();
>if ( feof(stdin) )
>   fprintf(stderr, "\nEOF detected, exiting..\n");
>   exit (0);

>if you read EOF from getchar(), the EOF indicator on stdin will be set.

Maybe, maybe not. getchar() returns EOF when either an end-of-file or
an error condition is encountered. To deal with this properly you would
have to test both feof() and ferror(). It is simpler and probably more
efficient to test the return value of getchar().

>BTW, according to the ANSI standard (i am quoting from PJ Plauger's "The
>Standard C Library") "fgetc function obtains the next character (if
>present) as an unsigned char converted to an int."

>my question then is whether it is appropriate to read this value into a
>char array rather than unsigned char array (assuming EOF is dealt with
>using feof rather than by inspecting the array element)?

Strictly converting the value to char produces an implementation-defined
result if the value is greater than CHAR_MAX. This is a weakness in the
language - since much of the standard library deals with pointers to
strings of type pointer to char people tend to overlook this and assume
the implementation "does the right thing". Luckily that tends to be



Sun, 10 Oct 1999 03:00:00 GMT  
 EOF, getchar() and preprocessor portability issues (Re: O

>Note the importance of making sure that c isn't EOF before passing it to
>the is*() functions which are likely to return unexpected results for
>non-char arguments (I don't know what the spec. says on this but it
>certainly happens in practice).

The functions in ctype.h are well-defined for an argument of value EOF,
you shouldn't have any problems with this specifically although any
other value that can't be represented as an unsigned char is a potential
problem. Therefore passing a general char value (which may be negative)
to these functions is dangerous it should be cast to unsigned char. It is
normal to test the return value of a function for failure before doing
anything else (and the EOF value is simply a failure indication from
getchar()) however in, for example:

    while (c != EOF && isalnum(c))
       c = getchar();

The test against EOF is redundant.



Sun, 10 Oct 1999 03:00:00 GMT  
 [ 3 post ] 

 Relevant Pages 

1. Help! getchar() and EOF

2. VC6 printf bug for while(ch=getchar()) != EOF)

3. printf error with while(ch=getchar())=eof)

4. getchar & EOF

5. getchar() and EOF, but casting it as (int)

6. getchar() with EOF

7. compilers os's and portability

8. DOS, OS/2, UNIX portability

9. Preprocessor Portability

10. Portability issue from VC++6 to VC++7

11. portability issues

12. ISO C portability issues.


Powered by phpBB® Forum Software