/** * select OP NUM - Select values read from stdin for which VAL OP NUM * holds. */ // +---------+-------------------------------------------------------- // | Headers | // +---------+ #include // For scanf, printf #include // For isdigit #include // For strcmp #include // For atoi // +-------+---------------------------------------------------------- // | Types | // +-------+ enum operator { LESS_THAN, // < LESS_EQUAL, // <= EQUALS, // == NOT_EQUAL, // != GREATER_EQUAL, // >= GREATER_THAN, // > BITWISE_OR, // | BITWISE_AND, // & BITWISE_XOR // ^ }; // +---------+-------------------------------------------------------- // | Helpers | // +---------+ /** * looks_like_int(str) * Determine if the string looks like an integer. */ int looks_like_int (char *str) { int i = 0; // Skip over leading sign. if ((str[0] == '+') || (str[0] == '-')) ++i; // Consider remaining characters. while (str[i] != '\0') { if (! isdigit (str[i])) return 0; ++i; } // while // We've read through all the characters. It must be an integer. return 1; } // looks_like_int /** * print_if_true (val, test) * Prints val if test holds. */ void print_if_true (int val, int test) { if (test) printf ("%d\n", val); } // print_if_true /** * string_equal (str1, str2) * Determine if two strings are equal. */ int string_equal (char str1[], char str2[]) { return (strcmp (str1, str2) == 0); } // string_equal // +------+----------------------------------------------------------- // | Main | // +------+ int main (int argc, char *argv[]) { int val; // The next number we've read int check; // The result of scanf int num; // The right-hand-side of the operator enum operator op; // The operator // Verify that we have the right number of parameters if (argc != 3) { printf ("Usage: %s OP NUM\n", argv[0]); return 1; } // Verify that the second paramter is a string that represents an // integer if (! looks_like_int (argv[2])) { printf ("Usage: %s OP NUM\n", argv[0]); printf (" %s is not an integer.\n", argv[2]); return 2; } // Get the number parameter num = atoi (argv[2]); // Get the operator parameter if (string_equal (argv[1], "<")) op = LESS_THAN; else if (string_equal (argv[1], "<=")) op = LESS_EQUAL; else if (string_equal (argv[1], "==")) op = EQUALS; else if (string_equal (argv[1], "!=")) op = NOT_EQUAL; else if (string_equal (argv[1], ">=")) op = GREATER_EQUAL; else if (string_equal (argv[1], ">")) op = GREATER_THAN; else if (string_equal (argv[1], "|")) op = BITWISE_OR; else if (string_equal (argv[1], "&")) op = BITWISE_AND; else if (string_equal (argv[1], "^")) op = BITWISE_XOR; else { printf ("Invalid operator: %s\n", argv[1]); printf (" Valid operators are <, <=, ==, !=, >, >=, |, &, and ^.\n"); return 3; } // Process each input value while ((check = scanf ("%d", &val)) != EOF) { // Special case: Failed to read a number and failed to reach // end of file. if (check == 0) { printf ("Invalid input: '%c'\n", getchar ()); continue; } // Normal case: Look at the operator and do the right thing switch (op) { case LESS_THAN: print_if_true (val, val < num); break; case LESS_EQUAL: print_if_true (val, val <= num); break; case EQUALS: print_if_true (val, val == num); break; case NOT_EQUAL: print_if_true (val, val != num); break; case GREATER_EQUAL: print_if_true (val, val >= num); break; case GREATER_THAN: print_if_true (val, val > num); break; case BITWISE_OR: print_if_true (val, val | num); break; case BITWISE_AND: print_if_true (val, val & num); break; case BITWISE_XOR: print_if_true (val, val ^ num); break; } // switch } // while // And we're done return 0; } // main