#include <iostream> // библиотке ввода-вывода
#include <string> // библиотека строк
#include <fstream> // библиотека файлов
#include <vector> // библиотека векторов (динамических массивов без ограничений памяти)

using namespace std;

void print_menu(){
    cout << "1. Create a new file" << endl;
    cout << "2. Read a file" << endl << endl;
}

string get_file_name(){ // функция на получение имени файла
    string file_name;

    cin >> file_name;
    cin.get();

    return file_name;
}

string get_file_text(string file_name){
    string file_text; // переменная, для хранения текста файла
    char s; // переменная, для хранения символа
    ifstream fin(file_name); // открытие файла на чтение под именем f1.txt

    if (!fin){ // если файл не открылся
        cout << "\nError during opening file. -1\n"; // вывод сообщения об ошибке
        exit(1); // завершение программы
    }

    // посимвольное считывание символов в файле и добавление в строку
	while (fin.get(s))
        file_text.push_back(s);

    fin.close(); // закрытие файла

    cout << "\nSuccsesfull text capture.\n" << endl;

    return file_text; // возврат полученной строки
}

void output_file_text(string file_text, string file_name){
    ofstream fout(file_name); // открытие файла на запись

    if (!fout){ // если файл не открылся
        cout << "\nError during opening file. -2\n"; // вывод сообщения об ошибке
        exit(2); // завершение программы
    }
    // цикл на прохождение строки
    for (int i = 0; i < file_text.size(); i++)
        fout << file_text[i]; // посимвольный вывод текста в файл  

    fout.close(); // закрытие файла

    cout << "\nText saved to file.\n";
}

void output_file_text(string file_name, int number){
    ofstream fout(file_name); // открытие файла на запись

    if (!fout){ // если файл не открылся
        cout << "\nError during opening file. -3\n"; // вывод сообщения об ошибке
        exit(3); // завершение программы
    }
    
    fout << number; // вывод числа в файл

    fout.close(); // закрытие файла

    cout << "\nNumber saved to file.\n" << endl;
}

vector <int> get_split_numbers(string file_text){
    vector <int> numbers; // массив для хранения слов строки (используется вектор для устранения ограничения на размер памяти)
    int start = 0; // счётчик начала слова
    int end = 0; // // счётчик конца слова
    int skip_count = 0; // счётчик пропусков

    for (int i = 0; i <= file_text.size(); i++) { // цикл на прохождение строки
        if (skip_count > 0){ // если есть ряд символов без букв
            skip_count--; // уменьшаем счётчик пропусков
            continue; // переходим на следующую итерацию до следующей буквы в строке
        }
        if (ispunct(file_text[i]) || isspace(file_text[i]) || file_text[i] == '\n' || file_text[i] == '\0'){ // если текущий символ строки не является буквой, то
            skip_count = 0; // обнуляем счётчик от нового слова
            end = i; // счётчик окончания равен текущему значению i
            numbers.push_back(stoi(file_text.substr(start, (end-start)))); // добавляем в массив слов часть строки от значения счётчика start. 
            // (end - start) нужен для вычисления количества символов

            while (ispunct(file_text[end]) || isspace(file_text[end])){ // пока текущий символ не является буквой,
                end++; // увеличиваем переменную end
                skip_count++; // увеличиваем количество пропусков в цикле по количеству итераций end
            } // цикл необходим для перехода к следующему слову, так как в задании не указан разделитель слов.

            start = end; // присваиваем счётчику start значение от end для пропуска не буквенных символов и продолжения работы.
        }
    }

    return numbers; // возвращаем отсортированный массив
}

void get_number(vector <int> numbers, string file_name){
    int number = numbers[0]; // присваиваем переменной number значение 2 элемента массива

    for (int i = 0; i < numbers.size(); i++){ // идём по чётным элементам массива
        if (number < numbers[i]) // если number < чем текущий элемент, то
            number = numbers[i]; // присваиваем number значение текущего элемента массива
    }

    output_file_text(file_name, number); // выводим полученное число в файл
}

int main(){
    int choise; // переменная, отвечающая за выбор пользователя
    string file_name; // имя файла
    string file_text; // текст файла
    vector <int> numbers; // массив для хранения чисел

    print_menu(); // вывод меню с вариантами
    cin >> choise; // получение выбора пользователя
    cin.get(); // очищает строку от оставшихся символов
    cout << endl;

    // ввод имени файла

    switch (choise) // проверка ввода пользователя
    {
    case 1: // если выбран вариант 1
        cout << "Input text:\n"; // ввод текста пользвателя
        getline(cin, file_text);

        cout << "\nFile for output inputed text: "; // ввод имени файла для вывода текста пользователя
        file_name = get_file_name();

        output_file_text(file_text, file_name); // вывод в файл текста пользователя

        file_text = get_file_text(file_name); // получение текста файла и его запись в переменную

        numbers = get_split_numbers(file_text); // получение массива целых чисел

        cout << "File for output result: "; // ввод имени файла для вывода результата
        file_name = get_file_name();

        get_number(numbers, file_name); // получение числа и его вывод в новый файл

        break;
    
    case 2: // если выбран вариант 2
        cout << "File for read: "; // ввод имени файла для чтения
        file_name = get_file_name();

        file_text = get_file_text(file_name); // получение текста файла и его запись в переменную

        numbers = get_split_numbers(file_text); // получение массива целых чисел

        cout << "File for output result: "; // ввод имени файла для вывода результата
        file_name = get_file_name();

        get_number(numbers, file_name); // получение числа и его вывод в новый файл

        break;
    
    default: // реакция по умолчанию
        cout << "\nIncorrect input\n"; // вывод сообщения об ошибке
        break; // остановка конструкции
    }

    return 0;
}