Reputation: 123
I have to create a Solitaire Program in C. I have the data structure set up but I have a question about comparing strings.
The user input has to look like "move [colour] [value] to [stack]".
Now my plan was to use strncmp
to see if the string contained "move" "color", etc. But with "value" I have a range of 13 acceptable inputs (Ace to King), which means I would need 13 different if-statements. Is there a more elegant way to check which "value" the input holds?
Examples: "move red 4 to 3" or "move black K to 6"
After I determined what the user specified, I have to find the given card in 7 double linked lists and move it to another list as specified by the user.
Thanks!
Upvotes: 1
Views: 1462
Reputation: 42139
If your input for value is a single character, you can simply check that the character exists in the list of valid characters:
const char valid_values[] = "A23456789TJQK";
if (strchr(valid_values, input_value[0])) {
// valid
} else {
// invalid
}
You can even use the character itself internally as-is as the representation of the value (since it is both unique and optimally small at 1 char
). Or you can convert to the numerical value by taking the index (such as by subtracting valid_values
from the non-NULL
return value of strchr
) and adding 1
.
If you wish to allow multiple alternatives (such as "A", "ace" or "two", "2", "deuce"), a simple alternative is to make an array of string-value pairs and iterate over them until a match is found or the end is reached:
struct value_string {
const char *string;
int value;
};
const struct value_string valid_values[] = {
{ .string = "A", .value = 1 },
{ .string = "ace", .value = 1 },
{ .string = "2", .value = 2 },
{ .string = "two", .value = 2 },
// …
{ .string = "K", .value = 13 },
{ .string = NULL, .value = 0 } // terminator
};
int card_value = 0;
for (const struct value_string *p = valid_values; p->string; ++p) {
if (strcmp(p->string, input_value) == 0) {
// found match
card_value = p->value;
break;
}
}
if (card_value) {
// valid
} else {
// invalid
}
The benefits of this kind of a solution are in the clarity and expandability of code, rather than on improving performance or reducing the total number of lines. For the best performance I would expect a look-up table (or simply a switch
) by first character and then manual character-by-character validation (of the remaining possibilities, only) to be hard to beat.
Upvotes: 1