0

just for fun I wrote this implementation of isalpha and it works but I have a lot of warnings, can you tell me how to fix them, or how can I do it in better way?

Warnings:

Line 6: comparision between pointer and integer

Line 23: passing argument 1 of 'pointer' makes pointer from integer without a cast

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

int my_isalpha(char *mark)
{
    if((((mark)>=0x41)&&((mark)<=0x5A)||((mark)>=0x61)&&((mark)<=0x7A))) //WARNING
     return 1;

   else
    return 0;
}


int main()
{
   char mark;
   int (*pointer)(char*);
   pointer=my_isalpha;

   printf("Your mark: ");
   scanf("%c",&mark);

   if(pointer(mark))  //WARNING
     printf("TRUE");

   else
    printf("FALSE");

  return 0;
}
NeviJ
  • 81
  • 1
  • 9

1 Answers1

3

This code is not portable since the standard does not even guarantee that the execution character set contains the letters of the Latin alphabet in sequence. See for example, here and here.

Here is a version that is more portable:

int my_isalpha(int c)
{
    char alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                      "abcdefghijklmnopqrstuvwxyz";
    char *letter = alphabet;

    while(*letter != '\0' && *letter != c)
        ++letter;

    if (*letter)
        return 1;

    return 0;
}

As @Dmitri pointed out in the comments, even this code might fail if the execution character set is changed at runtime in such a way the the numeric values of the characters are no longer the same as they were at compile time. So, it is best to use the standard library function isalpha(), which makes use of the current locale.

@KeithThompson suggested that my concern for portability might be somewhat misplaced, in that isalpha() is a library function that must work within the implementation that contains it, but is not itself required to be written in portable C. This is a good point, and I have no real defense other than to say that I was addressing the part of your question that asked, "how can I do it in a better way?"

With these caveats, I will leave my answer, for now....

Community
  • 1
  • 1
ad absurdum
  • 19,498
  • 5
  • 37
  • 60
  • Even what you've shown might break if the character set is changed at runtime -- which is another good reason to use the one in the standard library. – Dmitri Oct 25 '16 at 20:26
  • @Dmitri-- I agree about using the standard library version. I think the point that you are making is that if the locale changes, this method might fail, but that the version of `isalpha()` in `ctype.h` checks in the locale. On the other hand, the only alphabetical characters guaranteed to be in the character set by the standard are the 52 upper- and lower-case characters of the Latin alphabet listed above. Am I off-base here? – ad absurdum Oct 25 '16 at 20:37
  • An implementation of `isalpha` is free to use whatever implementation-specific tricks it likes. It's required to work within the C implementation it's part of. It's not required to be implemented in portable C. On the other hand, a *portable* implementation of `isalpha` is also an interesting exercise. – Keith Thompson Oct 25 '16 at 20:42
  • @KeithThompson-- Ahh... I see your point. I will revise my answer to address the issues that you and Dmitri have raised. – ad absurdum Oct 25 '16 at 20:49
  • Even if all those characters are in both the character set used when compiling and the one used at runtime, if the numeric values of those characters differ between the two character sets the code would still fail (you'd be checking the numeric values from the compile-time character set against characters from the runtime set). So the code is portable in that it doesn't care about the ordering of the alphabetic characters, but it's still only good for the character set it was compiled for (or a sufficiently similar one). – Dmitri Oct 25 '16 at 20:59