Thread: Getting weird results with isalpha

  1. #1
    Registered User
    Join Date
    Nov 2010
    Posts
    12

    Getting weird results with isalpha

    I wrote the following little test program to test out the isalpha function:

    Code:
    #include <stdio.h>
    #include <ctype.h>
    #include <stdlib.h>
    
    main(int argc, char * argv[] )
    {
       FILE * fp = fopen( argv[1], "r" );
    
       printf( "%d\n%d\n%d\n%d\n", isalpha(fgetc(fp)), isalpha(fgetc(fp)), isalpha(fgetc(fp)), isalpha(fgetc(fp)));
    
    }
    And ran it using this as my input text file:
    Code:
    a&b-
    And got the following output:
    Code:
    0
    1024
    0
    1024
    According to what I've read, the isalpha function should produce non-zero values when given the letters 'a' and 'b', and it should produce zero when given '&' and '-'. This is the exact opposite of what the above code shows. Can someone tell me what's going on? Could there be a bug in this function? I'm using gcc to compile.
    Last edited by itsthemac; 04-20-2011 at 08:13 PM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    The order of evaluation of arguments in a function call is implementation defined. Make those calls to fgetc before the call to printf, or make a separate call to printf for each character read.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by laserlight View Post
    The order of evaluation of arguments in a function call is implementation defined. Make those calls to fgetc before the call to printf, or make a separate call to printf for each character read.
    Agreed... a loop would be a good idea here...

  4. #4
    Registered User
    Join Date
    Nov 2010
    Posts
    12
    Quote Originally Posted by laserlight View Post
    The order of evaluation of arguments in a function call is implementation defined. Make those calls to fgetc before the call to printf, or make a separate call to printf for each character read.
    Thanks, got it to work using your suggestions. I never thought about the evaluation order thing, I'll keep it in mind for the next time I run into something like this. Now I have a follow-up question if you don't mind (just out of curiosity). I just ran this code segment
    Code:
       int i = 0;
       printf( "%d\n%d\n%d\n", i = i+1, i = i+1, i = i+1 );
    and expected to get this as a result (assuming that it evaluated the statements from right to left):
    Code:
    3
    2
    1
    but instead I got this:
    Code:
    3
    3
    3
    What is the reasoning behind this (if you know)? Were these evaluated at compile-time or something? What am I not thinking about?

  5. #5
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    It evaluated all the equations before printing...

    Right to left... printing happens last.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Most likely what happened here is that i = 0+1 = 1, then i = 1+1 = 2, then i = 2+1 =3, then i was used in all three cases.

    That said, what you have here is worse: there is undefined behaviour, not just implementation defined behaviour, because you modify i more than once between sequence points (the previous sequence point was prior to the call of printf; the next sequence point is after all the arguments to printf have been evaluated).
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Nov 2010
    Posts
    12
    Quote Originally Posted by laserlight View Post
    Most likely what happened here is that i = 0+1 = 1, then i = 1+1 = 2, then i = 2+1 =3, then i was used in all three cases.

    That said, what you have here is worse: there is undefined behaviour, not just implementation defined behaviour, because you modify i more than once between sequence points (the previous sequence point was prior to the call of printf; the next sequence point is after all the arguments to printf have been evaluated).
    Ok, thanks. I think my problem was that I thought that the assignment statement evaluated to the value being assigned. But I guess it evaluates to the value of the thing on the left of the assignment operator, after the assignment is done? Therefore, in my post above it was taking the value of i (the thing on the left in each assignment statement) each time (after all three assignments had completed), not what was actually assigned to i each individual time. Thanks.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by itsthemac
    I think my problem was that I thought that the assignment statement evaluated to the value being assigned.
    I don't have the C standard on hand to verify, but I think that it does.

    Quote Originally Posted by itsthemac
    But I guess it evaluates to the value of the thing on the left of the assignment operator, after the assignment is done?
    After assignment, the value of the object on the left of the assignment operator is the value being assigned.

    Quote Originally Posted by itsthemac
    Therefore, in my post above it was taking the value of i (the thing on the left in each assignment statement) each time (after all three assignments had completed), not what was actually assigned to i each individual time.
    As I stated, there is undefined behaviour. The output could also have been instead:
    Code:
    3
    2
    1
    or:
    Code:
    0
    0
    0
    or even:
    Code:
    Hello world!
    or you could have experienced a crash, etc, and it would all be perfectly acceptable, i.e., not a compiler bug.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Dot3 bumpmapping: weird results
    By psychopath in forum Game Programming
    Replies: 12
    Last Post: 02-09-2006, 01:40 PM
  2. Using isalpha()
    By Cmuppet in forum C Programming
    Replies: 4
    Last Post: 08-04-2004, 01:12 PM
  3. isalpha
    By mackol in forum C Programming
    Replies: 9
    Last Post: 11-29-2002, 02:55 PM
  4. isalpha
    By ygfperson in forum C Programming
    Replies: 3
    Last Post: 02-07-2002, 09:29 AM
  5. isalpha in for loop
    By itld in forum C++ Programming
    Replies: 9
    Last Post: 10-19-2001, 08:05 PM