a,ɑ
ɑ,ɒ
e,ɛ
i,ɪ
o,ɔ
u,ʊ
æ,a
æ,ɑ
ə,ʌ
ʌ,ɑ
e,ə
ɜ,ə
ə,ɯ
ɛ,æ
ɪ,e
ɔ,ɒ
u,y
ü,y
ö,ø
é,e
á,a
ó,o
å,ɔ
æ,ä
ö,œ
ò,o
ì,i
ù,u
â,a
ê,e
î,i
ô,o
û,u
ee,i
oo,u
ie,i
ei,aɪ
ai,aɪ
ou,aʊ
au,aʊ
p,b
t,d
k,g
s,z
b,m
m,p
n,t

----

//compare.h

#ifndef COMPARE_H
#define COMPARE_H

#include <glib.h>

// Структура для хранения звуковых соответствий
typedef struct {
    gchar *sound1;
    gchar *sound2;
} SoundCorrespondence;

// Функции для сравнения слов и формирования результата
GArray* find_sound_correspondences(const gchar *word1, const gchar *word2);
gchar* format_correspondences(GArray *correspondences, const gchar *language1, const gchar *language2);

// Функции для работы с файлами звуковых соответствий
void load_sound_correspondences(const gchar *filename);
void free_sound_correspondences();

#endif // COMPARE_H

----

//compare.c

#include <stdio.h>
#include <string.h>
#include <glib.h>
#include "compare.h"

// Массив звуковых соответствий
static GArray *correspondences_array = NULL;

// Функция для загрузки звуковых соответствий из файла
void load_sound_correspondences(const gchar *filename) {
    if (correspondences_array != NULL) {
        g_array_free(correspondences_array, TRUE);
    }

    correspondences_array = g_array_new(FALSE, FALSE, sizeof(SoundCorrespondence));

    // Открываем файл
    FILE *file = fopen(filename, "r");
    if (!file) {
        g_warning("Не удалось открыть файл с соответствиями: %s", filename);
        return;
    }

    char line[256];
    while (fgets(line, sizeof(line), file)) {
        gchar **tokens = g_strsplit(line, ",", 2);
        if (tokens[0] && tokens[1]) {
            gchar *sound1 = g_strstrip(tokens[0]);
            gchar *sound2 = g_strstrip(tokens[1]);

            SoundCorrespondence sc = { g_strdup(sound1), g_strdup(sound2) };
            g_array_append_val(correspondences_array, sc);
        }
        g_strfreev(tokens);
    }

    fclose(file);
}

// Функция для освобождения памяти массива соответствий
void free_sound_correspondences() {
    if (correspondences_array != NULL) {
        for (guint i = 0; i < correspondences_array->len; i++) {
            SoundCorrespondence sc = g_array_index(correspondences_array, SoundCorrespondence, i);
            g_free(sc.sound1);
            g_free(sc.sound2);
        }
        g_array_free(correspondences_array, TRUE);
        correspondences_array = NULL;
    }
}

// Функция для разбивки слова на звуки (предполагается посимвольная разбивка)
GArray* split_word_into_sounds(const gchar *word) {
    GArray *sounds = g_array_new(FALSE, FALSE, sizeof(gchar *));
    const gchar *p = word;

    while (*p) {
        gunichar c = g_utf8_get_char(p);
        int char_len = g_unichar_to_utf8(c, NULL);
        gchar *sound = g_utf8_substring(p, 0, 1);
        g_array_append_val(sounds, sound);
        p = g_utf8_next_char(p);
    }

    return sounds;
}

// Функция для освобождения памяти массива звуков
void free_sounds_array(GArray *sounds) {
    for (guint i = 0; i < sounds->len; i++) {
        gchar *sound = g_array_index(sounds, gchar *, i);
        g_free(sound);
    }
    g_array_free(sounds, TRUE);
}

// Функция для поиска звуковых соответствий между двумя словами
GArray* find_sound_correspondences(const gchar *word1, const gchar *word2) {
    GArray *result = g_array_new(FALSE, FALSE, sizeof(SoundCorrespondence));

    GArray *sounds1 = split_word_into_sounds(word1);
    GArray *sounds2 = split_word_into_sounds(word2);

    guint len = MIN(sounds1->len, sounds2->len);

    for (guint i = 0; i < len; i++) {
        gchar *sound1 = g_array_index(sounds1, gchar *, i);
        gchar *sound2 = g_array_index(sounds2, gchar *, i);

        // Если звуки идентичны
        if (g_strcmp0(sound1, sound2) == 0) {
            // Добавляем в результат как одинаковый звук
            SoundCorrespondence sc = { g_strdup(sound1), g_strdup(sound2) };
            g_array_append_val(result, sc);
        } else if (correspondences_array != NULL) {
            // Проверяем, есть ли данная пара в списке соответствий
            for (guint j = 0; j < correspondences_array->len; j++) {
                SoundCorrespondence corr = g_array_index(correspondences_array, SoundCorrespondence, j);
                if ((g_strcmp0(sound1, corr.sound1) == 0 && g_strcmp0(sound2, corr.sound2) == 0) ||
                    (g_strcmp0(sound1, corr.sound2) == 0 && g_strcmp0(sound2, corr.sound1) == 0)) {
                    SoundCorrespondence sc = { g_strdup(sound1), g_strdup(sound2) };
                    g_array_append_val(result, sc);
                    break;
                }
            }
        }
    }

    free_sounds_array(sounds1);
    free_sounds_array(sounds2);

    return result;
}

// Функция для формирования строки с результатами
gchar* format_correspondences(GArray *correspondences, const gchar *language1, const gchar *language2) {
    GString *result = g_string_new("");

    if (correspondences->len == 0) {
        g_string_append(result, "Звуковые соответствия не обнаружены.");
    } else {
        for (guint i = 0; i < correspondences->len; i++) {
            SoundCorrespondence sc = g_array_index(correspondences, SoundCorrespondence, i);
            if (g_strcmp0(sc.sound1, sc.sound2) == 0) {
                // Идентичные звуки
                gchar *line = g_strdup_printf("В %s и %s одинаковый звук: /%s/.\n", language1, language2, sc.sound1);
                g_string_append(result, line);
                g_free(line);
            } else {
                // Различные звуки с соответствием
                gchar *line = g_strdup_printf("Вероятные звуковые соответствия в %s и %s: /%s/ и /%s/.\n", language1, language2, sc.sound1, sc.sound2);
                g_string_append(result, line);
                g_free(line);
            }
            g_free(sc.sound1);
            g_free(sc.sound2);
        }
    }

    g_array_free(correspondences, TRUE);

    gchar *final_result = result->str;
    g_string_free(result, FALSE);
    return final_result;
}

----

//main.c

 #include <gtk/gtk.h>
#include "compare.h"

static void on_compare_button_clicked(GtkButton *button, gpointer user_data) {
    GtkEntry *entry_word1 = GTK_ENTRY(g_object_get_data(G_OBJECT(button), "entry_word1"));
    GtkEntry *entry_word2 = GTK_ENTRY(g_object_get_data(G_OBJECT(button), "entry_word2"));
    GtkEntry *entry_lang1 = GTK_ENTRY(g_object_get_data(G_OBJECT(button), "entry_lang1"));
    GtkEntry *entry_lang2 = GTK_ENTRY(g_object_get_data(G_OBJECT(button), "entry_lang2"));
    GtkTextView *textview_results = GTK_TEXT_VIEW(g_object_get_data(G_OBJECT(button), "textview_results"));

    const gchar *word1 = gtk_entry_get_text(entry_word1);
    const gchar *word2 = gtk_entry_get_text(entry_word2);
    const gchar *lang1 = gtk_entry_get_text(entry_lang1);
    const gchar *lang2 = gtk_entry_get_text(entry_lang2);

    if (g_strcmp0(word1, "") == 0 || g_strcmp0(word2, "") == 0) {
        GtkWidget *dialog = gtk_message_dialog_new(NULL,
            GTK_DIALOG_DESTROY_WITH_PARENT,
            GTK_MESSAGE_ERROR,
            GTK_BUTTONS_OK,
            "Пожалуйста, введите оба слова для сравнения.");
        gtk_dialog_run(GTK_DIALOG(dialog));
        gtk_widget_destroy(dialog);
        return;
    }

    GArray *correspondences = find_sound_correspondences(word1, word2);
    gchar *result_text = format_correspondences(correspondences, lang1, lang2);

    GtkTextBuffer *buffer = gtk_text_view_get_buffer(textview_results);
    gtk_text_buffer_set_text(buffer, result_text, -1);
    g_free(result_text);
}

int main(int argc, char *argv[]) {
    gtk_init(&argc, &argv);

    // Загружаем звуковые соответствия из файла
    load_sound_correspondences("sound_correspondences.csv");

    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Сравнение слов");
    gtk_window_set_default_size(GTK_WINDOW(window), 600, 400);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    GtkWidget *grid = gtk_grid_new();
    gtk_container_add(GTK_CONTAINER(window), grid);

    // Метки и поля ввода для языков и слов
    GtkWidget *label_lang1 = gtk_label_new("Язык 1:");
    GtkWidget *entry_lang1 = gtk_entry_new();
    gtk_entry_set_text(GTK_ENTRY(entry_lang1), "Язык 1");

    GtkWidget *label_lang2 = gtk_label_new("Язык 2:");
    GtkWidget *entry_lang2 = gtk_entry_new();
    gtk_entry_set_text(GTK_ENTRY(entry_lang2), "Язык 2");

    GtkWidget *label_word1 = gtk_label_new("Слово 1:");
    GtkWidget *entry_word1 = gtk_entry_new();

    GtkWidget *label_word2 = gtk_label_new("Слово 2:");
    GtkWidget *entry_word2 = gtk_entry_new();

    GtkWidget *button_compare = gtk_button_new_with_label("Сравнить");

    // Поле для вывода результатов
    GtkWidget *textview_results = gtk_text_view_new();
    gtk_text_view_set_editable(GTK_TEXT_VIEW(textview_results), FALSE);

    // Располагаем элементы в сетке
    gtk_grid_attach(GTK_GRID(grid), label_lang1, 0, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), entry_lang1, 1, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), label_lang2, 2, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), entry_lang2, 3, 0, 1, 1);

    gtk_grid_attach(GTK_GRID(grid), label_word1, 0, 1, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), entry_word1, 1, 1, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), label_word2, 2, 1, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), entry_word2, 3, 1, 1, 1);

    gtk_grid_attach(GTK_GRID(grid), button_compare, 1, 2, 2, 1);
    gtk_grid_attach(GTK_GRID(grid), textview_results, 0, 3, 4, 1);

    // Связываем кнопку со слотами
    g_object_set_data(G_OBJECT(button_compare), "entry_word1", entry_word1);
    g_object_set_data(G_OBJECT(button_compare), "entry_word2", entry_word2);
    g_object_set_data(G_OBJECT(button_compare), "entry_lang1", entry_lang1);
    g_object_set_data(G_OBJECT(button_compare), "entry_lang2", entry_lang2);
    g_object_set_data(G_OBJECT(button_compare), "textview_results", textview_results);
    g_signal_connect(button_compare, "clicked", G_CALLBACK(on_compare_button_clicked), NULL);

    gtk_widget_show_all(window);
    gtk_main();

    // Освобождаем память
    free_sound_correspondences();

    return 0;
}

---- Makefile

 CC = gcc
CFLAGS = `pkg-config --cflags gtk+-3.0 glib-2.0`
LIBS = `pkg-config --libs gtk+-3.0 glib-2.0`

all: main

main: main.c compare.c compare.h
	$(CC) -o main main.c compare.c $(CFLAGS) $(LIBS)

clean:
	rm -f main

Проанализируй этот код, сделай интерфейс программы более симетричным, добавь возможность добавлять колонку с языком для сравнения, добавь возможность сравнивать несколько взаимозаменяемых звуков из таблицы csv, а не только 2 звука. Расширь таблицу csv новыми возможными звуковыми соответствиями из расширенной латиници и МФА. Напиши  полную обновленную версию всех файлов