Add TP 7 correction.
[TD_C.git] / TP_7_C / exo2-extra.c
diff --git a/TP_7_C/exo2-extra.c b/TP_7_C/exo2-extra.c
new file mode 100644 (file)
index 0000000..2250cfd
--- /dev/null
@@ -0,0 +1,119 @@
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+/** Pointer to a function with this profile */
+typedef int(*operation_cb)(int v1, int v2);
+
+/** Describe a single operation */
+typedef struct {
+    const char* label;
+    operation_cb cb;
+} operation_t;
+
+int doAddition(int v1, int v2);
+int doSubstraction(int v1, int v2);
+int doMultiplication(int v1, int v2);
+int doXOR(int v1, int v2);
+
+/** All available operations */
+operation_t operations[4] = {
+    {
+        "Addition",
+        doAddition
+    },
+    {
+        "Substraction",
+        doSubstraction
+    },
+    {
+        "Multiplication",
+        doMultiplication
+    },
+    {
+        "XOR",
+        doXOR
+    }
+};
+#define operations_count ((int) (sizeof(operations) / sizeof(operations[0])))
+
+/** Display a prompt to the user then wait for an integer input. */
+void promptValue(const char* prompt, int* value) {
+    printf("%s:\n", prompt);
+    scanf("%d", value);
+}
+
+void displayMenuEntry(int index, const char* label) {
+    printf("%d | %s\n", index, label);
+}
+
+/** Display all available operations and an EXIT option. */
+void displayMenu() {
+    for (int menuIndex = 0; menuIndex < operations_count; ++menuIndex) {
+        displayMenuEntry(menuIndex + 1, operations[menuIndex].label);
+    }
+
+    displayMenuEntry(operations_count + 1, "Exit");
+}
+
+/** Prompt the user for his operation choice.
+ *
+ * @return The selected operation. If the exit option is chosen, return NULL
+ */
+operation_t* promptOperation() {
+    displayMenu();
+
+    do {
+        int result;
+        promptValue("Choose an option", &result);
+
+        if (result == (operations_count + 1)) {
+            return NULL;
+        }
+
+        if (result >= 1 && result <= operations_count) {
+            return &operations[result - 1];
+        }
+
+        printf("Please choose a valid option (1-%d)\n", operations_count);
+    } while (true);
+}
+
+int doAddition(int v1, int v2) {
+    return v1 + v2;
+}
+
+int doSubstraction(int v1, int v2) {
+    return v1 - v2;
+}
+
+int doMultiplication(int v1, int v2) {
+    return v1 * v2;
+}
+
+int doXOR(int v1, int v2) {
+    return v1 ^ v2;
+}
+
+int main() {
+    operation_t* operation = promptOperation();
+
+    if (operation == NULL) {
+        return 0;
+    }
+
+    int initialValue;
+    promptValue("Initial value", &initialValue);
+
+    do {
+        int nextValue;
+        promptValue("Next value", &nextValue);
+
+        if (nextValue == 0) {
+            break;
+        }
+
+        initialValue = operation->cb(initialValue, nextValue);
+        printf("Result: %d\n", initialValue);
+    } while (true);
+}