Mat Mat - 1 month ago 15
C Question

Matching regular characters using scanf in C

I want to validate user input, making sure they enter only regular characters (combination of 0-9, A-Z, and a-z).

This is what I have, but its matching strings like "adsifj%a%%dosif". Which I do not want. It wont match if those invalid characters were at the beginning. How can I fix this?

int main(){
char name[128];

int match = scanf(" %[0-9a-zA-Z^\n]", name);
printf("%d", match);

if (match == 1){
printf("Matched");
}else{
printf("Invalid");
}
return 0;


}

Answer

Instead of:

int match = scanf(" %[0-9a-zA-Z^\n]", name);

you should write:

char line[80], name[80];
char toomuch;

if (fgets(line, sizeof line, stdin) != NULL && sscanf(line, " %79[0-9A-Za-z] %c", name, &toomuch) == 1) {
    printf("name=(%s)\n", name);
}

First, read a complete line using fgets. Then, split that line into tokens using sscanf. The first token is the regular name, and the second token is the next character after the name that is not whitespace.

The input is valid if the line consists of any whitespace, followed by a regular word, followed by any whitespace, and then ends. There must not be any other characters left. This is why I am reading 2 tokens (name and toomuch) but only expecting 1 to be successfully read (the == 1).

Splitting the work between fgets and sscanf is necessary. If they were combined into scanf(" %80[0-9A-Za-z] %c", name, &toomuch), the %c would need to read a second line sometimes, especially when you enter a correct regular name.

Note the %79 in the argument to sscanf. It is necessary to prevent a buffer overflow.