CloudWave
CloudWave

Reputation: 1095

C - !isalpha treate character of type unsigned char as not alphabetic

The function reads two input from user, both of the input are string but one should contain only numbers and the other should contain only characters. I have a validate function to check if string contains not alphabetic characters.

bool checkString( const char inputString[] ){
   
unsigned char inputChar;

bool errorFree = true;

while ( ( inputChar = *inputString ) ){

    if(!isalpha(inputChar)){
         errorFree = false;
    }

     ++inputString;

} 

return errorFree;


}

the !isalpha(inputChar) keeps treating normal character as not alphabetic, and run set errorFree to false. Before calling this function another string input was taken. The full function:

void createNewEmployee(char* header, char* records, long size ){

char newID[MAX];

int numberOfRecords = getNumberOfRecords(records);

//printf("num of records: %d",numberOfRecords);

createID(numberOfRecords, (char *) newID );

//printf("%s",newID); 

  char telNum[15];
  char name[40];
  bool telValidated = false;
  bool nameValidated = false;

 while(!telValidated){

        fputs("enter some number: ", stdout);

        fflush(stdout);

        if ( fgets(telNum, sizeof(telNum), stdin) ) {

            int number;

            if ( sscanf(telNum, "%d", &number) == 1 ) {
                
                //   printf("is all number = %d\n", number);

                telValidated = true;
            }

            else{
                printf("enter numbers only\n");
            }
        }
 }

  while(!nameValidated){

        fputs("enter name: ", stdout);

        fflush(stdout);

        if ( fgets(name, sizeof(name), stdin) ) {

            if(checkString(name)){
                printf("error Free");
                nameValidated = true;
            }

            else{
                printf("enter characters only!\n");
            }
        }
 }

addNewRecord(newID,"anotherNew,01293073232,newDepartment\n",header, records, size);

}

I think it might be because of the input remains in the last fgets got brought into the current fgets?

enter image description here

Upvotes: 0

Views: 236

Answers (3)

chux
chux

Reputation: 154228

OP's code is likely failing as it still retains a trailing '\n', causing checkString() to return incorrectly.

Candidate simplification that does not require prior removal of a '\n' from the end of the line:

bool checkString(const char inputLine[]) {
  while (isalpha(*(unsigned char*)inputLine)) {
    inputLine++;
  }
  return *inputLine == '\0' || *inputLine == '\n';
}

Upvotes: 1

Ben
Ben

Reputation: 195

This is why it's always helpful to post your main program too where you test it. My guess is, based on the way you're getting input, maybe you're storing a newline at the end of the string which is not an alphabetic character.

Also, your function has a more elegant solution. As soon as you find an error, there's no need to continue looking through the string. So, just return false as soon as this happens. Technically, it doesn't matter much since your function and mine both are O(N) runtime. However, it's still good to think in this way. What if you had a string of 1000 characters, and the 3rd character was not alphabetical. Why then continue to check all 997 other characters?

bool checkString(const char inputString[]) {
    while (*inputString) {
        if (!isalpha(*inputString))
            return false;
        ++inputString;
    }
    return true;
}

Upvotes: 5

Eric Postpischil
Eric Postpischil

Reputation: 224312

When fgets reads a line, it includes the newline character, '\n', in the buffer. The newline character is not alphabetic, so isalpha returns false for it.

Fix your code to remove or ignore the newline character in the buffer.

Upvotes: 5

Related Questions