usaa24/cv7/program.c

141 lines
4.5 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_TEXT 256
// Структура вузла дерева
typedef struct Node {
char text[MAX_TEXT];
struct Node *yes;
struct Node *no;
} Node;
// Функція для створення нового вузла
Node* createNode(const char* text) {
Node* node = (Node*)malloc(sizeof(Node));
if (node) {
strncpy(node->text, text, MAX_TEXT);
node->yes = NULL;
node->no = NULL;
}
return node;
}
// Завантаження дерева з файлу
Node* loadTree(FILE *file) {
char line[MAX_TEXT];
if (!fgets(line, sizeof(line), file)) {
return NULL;
}
line[strcspn(line, "\n")] = 0; // Видаляємо новий рядок
// Визначаємо, чи це листовий вузол
if (line[0] == '*') {
return createNode(line + 1); // Видаляємо символ '*' на початку
}
// Створюємо внутрішній вузол з двома піддеревами
Node *node = createNode(line);
node->yes = loadTree(file);
node->no = loadTree(file);
return node;
}
// Функція для підрахунку вузлів (листових та внутрішніх)
void countNodes(Node* root, int* leafCount, int* internalCount) {
if (root == NULL) {
return;
}
if (root->yes == NULL && root->no == NULL) {
(*leafCount)++;
} else {
(*internalCount)++;
countNodes(root->yes, leafCount, internalCount);
countNodes(root->no, leafCount, internalCount);
}
}
// Функція для проведення діалогу з користувачем
void interact(Node* root) {
Node* current = root;
while (current->yes != NULL && current->no != NULL) {
printf("%s (a/n): ", current->text);
char answer;
// Читання одного символа для відповіді
int res = fgetc(stdin); // Використовуємо fgetc для точного контролю вводу
// Пропускаємо всі зайві символи нового рядка або пробіли
while (res == '\n' || res == ' ' || res == '\t') {
res = fgetc(stdin);
}
if (res == EOF) {
printf("Некоректна відповідь! Завершення програми.\n");
return;
}
answer = (char)res; // Зберігаємо введений символ
if (answer == 'a') {
current = current->yes;
} else if (answer == 'n') {
current = current->no;
} else {
printf("Некоректна відповідь! Завершення програми.\n");
return;
}
}
printf("Результат: %s\n", current->text);
}
// Функція для очищення пам'яті дерева
void freeTree(Node* root) {
if (root == NULL) {
return;
}
freeTree(root->yes);
freeTree(root->no);
free(root);
}
int main(int argc, char *argv[]) {
// Відкриваємо файл або використовуємо стандартний вхід
FILE *file;
if (argc > 1) {
file = fopen(argv[1], "r");
if (!file) {
printf("Помилка: не вдалося відкрити файл %s.\n", argv[1]);
return 1;
}
} else {
file = stdin; // Використовуємо стандартний вхід, якщо файл не заданий
}
// Завантажуємо дерево з файлу
Node* root = loadTree(file);
if (file != stdin) fclose(file);
// Перевірка на успішне завантаження дерева
if (!root) {
printf("Помилка: дерево не було завантажене.\n");
return 1;
}
// Підрахунок вузлів
int leafCount = 0, internalCount = 0;
countNodes(root, &leafCount, &internalCount);
printf("Загальна кількість товарів (листових вузлів): %d\n", leafCount);
printf("Кількість питань (внутрішніх вузлів): %d\n", internalCount);
// Інтерактивна взаємодія з користувачем
printf("Починаємо діалог...\n");
interact(root);
// Очищення пам'яті
freeTree(root);
printf("Програма завершена успішно.\n");
return 0;
}