// compare.c

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

// Удалённое повторное определение структуры

// Массив звуковых соответствий из вашего первого сообщения
const SoundCorrespondence correspondences[] = {
    {"p", "b"}, {"p", "f"}, {"b", "f"},
    {"t", "d"}, {"t", "θ"}, {"t", "ð"},
    {"k", "g"}, {"k", "h"}, {"k", "x"},
    {"s", "z"}, {"s", "ʃ"}, {"s", "ʒ"},
    {"m", "n"}, {"m", "ŋ"}, {"n", "ŋ"},
    {"r", "l"},
    {"w", "v"}, {"w", "β"},
    {"j", "ʝ"}, {"j", "dʒ"},
    {"e", "i"}, {"e", "ɛ"},
    {"o", "u"}, {"o", "ɔ"},
    {"æ", "a"}, {"æ", "ɑ"},
    {"θ", "f"}, {"θ", "h"},
    {"d", "ð"}, {"d", "z"},
    {"k", "tʃ"}, {"k", "ʃ"},
    {"g", "ʒ"}, {"g", "dʒ"},
    {"p", "pf"}, {"p", "f"},
    {"t", "ts"}, {"t", "s"},
    {"b", "v"}, {"b", "w"},
    {"h", "ʔ"},
    {"l", "ɾ"}, {"l", "r"}
};

// Количество звуковых соответствий
const int num_correspondences = sizeof(correspondences) / sizeof(SoundCorrespondence);

// Функция для разбивки слова на звуки (предполагается посимвольная разбивка)
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 {
            // Проверяем, есть ли данная пара в списке соответствий
            for (int j = 0; j < num_correspondences; j++) {
                if ((g_strcmp0(sound1, correspondences[j].sound1) == 0 && g_strcmp0(sound2, correspondences[j].sound2) == 0) ||
                    (g_strcmp0(sound1, correspondences[j].sound2) == 0 && g_strcmp0(sound2, correspondences[j].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;
}

// 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);

#endif // COMPARE_H

На основе этого кода разработай интерфейс на gtk 3.24 с табличным интерфейсом для сравнения слов в одной строке и нахождения регулярных звуковых соответствий между словами. Дополни таблицу из compare.c схожими и взаимозаменяемыми гласными из расширенной латиницы и МФА. Напиши полную версию всех обновленных кодов.