Сохранить фрагмент из видеофайла (нарезка на фрагменты)

Ответить
ya
^-^
Сообщения: 2336
Зарегистрирован: 16 дек 2021, 19:56

Сохранить фрагмент из видеофайла (нарезка на фрагменты)

Сообщение ya »

Компиляция: Использование:

Код: Выделить всё

splitter видеофайл.mp4 0:0:59 0:1:37
где 0:0:59 - начало фрагмента, а 0:1:37 - конец фрагмента, причём конец фрагмента может отсутствовать
Вложения
splitter.zip
(676.35 КБ) 36 скачиваний
splitter.zip
(676.35 КБ) 36 скачиваний
ya
^-^
Сообщения: 2336
Зарегистрирован: 16 дек 2021, 19:56

Re: Сохранить фрагмент из видеофайла (нарезка на фрагменты)

Сообщение ya »

добавлено: если ранее создан файл с метками времени, то не создавать его заново

splitter.cpp

Код: Выделить всё

#include <iostream>
#include <iomanip>
#include <sstream>
#include <vector>
#include <string>
#include <fstream>
#include <cstdlib> // Для system()
#include <algorithm>
#include <ctime>   // Для работы с датой и временем

const std::string OUTPUT_SUFFIX = ".output.mp4"; // Суффикс для выходного файла

struct Time {
    int hours, minutes;
    double seconds;

    Time(int h = 0, int m = 0, double s = 0.0) : hours(h), minutes(m), seconds(s) {}

    std::string toString() const {
        std::stringstream ss;
        ss << std::setw(2) << std::setfill('0') << hours << ":"
           << std::setw(2) << std::setfill('0') << minutes << ":"
           << std::fixed << std::setprecision(6) << std::setfill('0') << seconds;
        return ss.str();
    }

    bool operator<(const Time& other) const {
        if (hours != other.hours) return hours < other.hours;
        if (minutes != other.minutes) return minutes < other.minutes;
        return seconds < other.seconds;
    }

    bool operator>(const Time& other) const {
        if (hours != other.hours) return hours > other.hours;
        if (minutes != other.minutes) return minutes > other.minutes;
        return seconds > other.seconds;
    }

    void subtract(double sec) {
        seconds -= sec;

        if (seconds < 0) {
            seconds += 60;
            minutes--;
        }

        if (minutes < 0) {
            minutes += 60;
            hours--;
        }

        if (hours < 0) {
            hours = 0;
            minutes = 0;
            seconds = 0.0;
        }
    }
};

bool runFFProbe(const std::string& input_file, const std::string& output_file) {
    std::string command = "ffprobe -i \"" + input_file + "\" -select_streams v -skip_frame nokey -show_frames -show_entries frame=pkt_pts_time -sexagesimal -print_format csv > \"" + output_file + "\"";
    return system(command.c_str()) == 0; // Возвращает true, если команда выполнена успешно
}

bool checkIfFileExists(const std::string& filename) {
    std::ifstream file(filename);
    return file.good();
}

void formatTimestamps(const std::string& input_file, const std::string& output_file) {
    std::ifstream infile(input_file);
    std::ofstream outfile(output_file);
    std::string line;
    
    while (std::getline(infile, line)) {
        size_t comma_pos = line.find(',');
        if (comma_pos != std::string::npos) {
            // Печатаем значение времени во втором столбце
            outfile << line.substr(comma_pos + 1) << std::endl;
        }
    }
}

std::vector<Time> readKeyframesFromFile(const std::string& filename) {
    std::ifstream file(filename);
    std::vector<Time> timestamps;
    std::string line;

    while (std::getline(file, line)) {
        std::istringstream ss(line);
        int h, m;
        double s;

        char colon1, colon2;
        ss >> h >> colon1 >> m >> colon2 >> s;

        if (ss && colon1 == ':' && colon2 == ':') {
            timestamps.emplace_back(h, m, s);
        }
    }

    return timestamps;
}

Time findMaxTimeLessThan(const std::string& filename, const Time& user_time) {
    std::ifstream file(filename);
    std::string line;
    Time max_time(0, 0, 0.0);

    while (std::getline(file, line)) {
        std::istringstream ss(line);
        int h, m;
        double s;

        char colon1, colon2;
        ss >> h >> colon1 >> m >> colon2 >> s;

        if (ss && colon1 == ':' && colon2 == ':') {
            Time current_time(h, m, s);
            if (current_time < user_time && current_time > max_time) {
                max_time = current_time;
            }
        }
    }
    return max_time;
}

// Функция для получения текущей даты и времени в нужном формате
std::string getCurrentDateTimeString() {
    std::time_t now = std::time(nullptr);
    std::tm* local_time = std::localtime(&now);
    
    std::ostringstream oss;
    oss << std::put_time(local_time, "%Y.%m.%d_%H-%M-%S");
    
    return oss.str();
}

// Функция для извлечения расширения файла
std::string getFileExtension(const std::string& filename) {
    size_t dot_pos = filename.rfind('.');
    if (dot_pos != std::string::npos) {
        return filename.substr(dot_pos); // Возвращает все, что после последней точки
    }
    return ""; // Если точка не найдена, возвращаем пустую строку
}

int main(int argc, char* argv[]) {
    if (argc < 3) {
        std::cerr << "Usage: " << argv[0] << " <input_file> <time_to_compare> <end_time (optional)>" << std::endl;
        return 1;
    }

    std::string input_file = argv[1];
    std::string search_time_str = argv[2];
    std::string end_time_str = (argc > 3) ? argv[3] : ""; // Опциональный третий аргумент

    // Генерация выходного файла ключевых кадров
    std::string keyframe_file = input_file + "_keyframes.txt";
	if (!checkIfFileExists(keyframe_file))
	{
    // Запуск ffprobe для извлечения ключевых кадров
    if (!runFFProbe(input_file, keyframe_file)) {
        std::cerr << "Error running ffprobe." << std::endl;
        return 1;
    }

    // Создание файла с отформатированными временными метками
    std::string formatted_keyframe_file = input_file + "_formatted_keyframes.txt";
    formatTimestamps(keyframe_file, formatted_keyframe_file);
    
    // Удаление оригинального файла с ключевыми кадрами
    remove(keyframe_file.c_str());
    
    // Переименование отформатированного файла
    rename(formatted_keyframe_file.c_str(), keyframe_file.c_str());
	}
    // Разбор введенного времени пользователем
    std::istringstream ss(search_time_str);
    int h, m;
    double s;
    char colon1, colon2;
    ss >> h >> colon1 >> m >> colon2 >> s;

    Time user_time(h, m, s);

    // Поиск наибольшего значения временной метки, меньшего чем user_time
    Time max_time = findMaxTimeLessThan(keyframe_file, user_time);

    // Вывод результата
    if (max_time.seconds > 0) {
        std::cout << "The largest time less than " << user_time.toString() << " is " << max_time.toString() << std::endl;
        
        max_time.subtract(0.1); // Вычитаем 0.1 секунды
        std::cout << "The time after subtracting 0:0:0.1 is " << max_time.toString() << std::endl;

        // Формирование команды ffmpeg
//        std::string current_datetime_suffix = getCurrentDateTimeString();
//        std::string output_file = input_file + "." + current_datetime_suffix + ".mp4"; 

		// Извлечение расширения входного файла
        std::string file_extension = getFileExtension(input_file);
        std::string current_datetime_suffix = getCurrentDateTimeString();
        
        // Создание имени выходного файла с учетом расширения
        std::string output_file = input_file.substr(0, input_file.size() - file_extension.size()) + "." + current_datetime_suffix + file_extension;
        
        // Формирование команды ffmpeg
        std::string command = "ffmpeg -i \"" + input_file + "\" -map_metadata -1 -map_chapters -1 -avoid_negative_ts make_zero -ss " +
                              max_time.toString() + (end_time_str.empty() ? " " : (" -to " + end_time_str) ) +
                              " -c copy \"" + output_file + "\"";

        // Выполнение команды ffmpeg
        if (system(command.c_str()) != 0) {
            std::cerr << "Error running ffmpeg." << std::endl;
            return 1;
        }
    } else {
        std::cout << "No time found less than " << user_time.toString() << "." << std::endl;
    }

    return 0;
}
Makefile

Код: Выделить всё

# Определяем компилятор и флаги компиляции
CXX = g++
CXXFLAGS = -std=c++11 -Wall -Wextra

# Основной целевой файл
TARGET = splitter

# Исходные файлы
SRCS = splitter.cpp  # Замените 'main.cpp' на имя вашего файла с кодом

# Объектные файлы
OBJS = $(SRCS:.cpp=.o)

# Правило по умолчанию для сборки
all: $(TARGET)

# Линковка объекта в исполняемый файл
$(TARGET): $(OBJS)
	$(CXX) $(OBJS) -o $(TARGET)

# Правило для компиляции исходников в объектные файлы
%.o: %.cpp
	$(CXX) $(CXXFLAGS) -c $< -o $@

# Правило для очистки
clean:
	rm -f $(OBJS) $(TARGET)

.PHONY: all clean
Вложения
splitter.zip
исходники и откомпилированный экзэшник
(669.41 КБ) 35 скачиваний
splitter.zip
исходники и откомпилированный экзэшник
(669.41 КБ) 35 скачиваний
ya
^-^
Сообщения: 2336
Зарегистрирован: 16 дек 2021, 19:56

Re: Сохранить фрагмент из видеофайла (нарезка на фрагменты)

Сообщение ya »

Внесённые изменения: рефакторинг кода

splitter1.cpp

Код: Выделить всё

#include <iostream>
#include <iomanip>
#include <sstream>
#include <vector>
#include <string>
#include <fstream>
#include <cstdlib> // Для system()
#include <algorithm>
#include <ctime>   // Для работы с датой и временем

class Time {
private:
    int hours, minutes;
    double seconds;

public:
    Time(int h = 0, int m = 0, double s = 0.0) : hours(h), minutes(m), seconds(s) {}

    std::string toString() const {
        std::stringstream ss;
        ss << std::setw(2) << std::setfill('0') << hours << ":"
           << std::setw(2) << std::setfill('0') << minutes << ":"
           << std::fixed << std::setprecision(6) << std::setfill('0') << seconds;
        return ss.str();
    }

    bool operator<(const Time& other) const {
        return std::tie(hours, minutes, seconds) < std::tie(other.hours, other.minutes, other.seconds);
    }

    bool operator>(const Time& other) const {
        return std::tie(hours, minutes, seconds) > std::tie(other.hours, other.minutes, other.seconds);
    }

    void subtract(double sec) {
        seconds -= sec;
        while (seconds < 0) {
            seconds += 60;
            minutes--;
        }
        while (minutes < 0) {
            minutes += 60;
            hours--;
        }
        if (hours < 0) {
            hours = minutes = 0;
            seconds = 0.0;
        }
    }

    // Добавим метод для проверки валидности времени
    bool isValid() const {
        return (hours >= 0 && minutes >= 0 && seconds >= 0);
    }

    // Метод для доступа к полю seconds
    double getSeconds() const {
        return seconds;
    }
};

class FrameExtractor {
public:
    static bool runFFProbe(const std::string& input_file, const std::string& output_file) {
        std::string command = "ffprobe -i \"" + input_file + "\" -select_streams v -skip_frame nokey -show_frames " 
                              "-show_entries frame=pkt_pts_time -sexagesimal -print_format csv > \"" + output_file + "\"";
        return system(command.c_str()) == 0; // Возвращает true, если команда выполнена успешно
    }

    static void formatTimestamps(const std::string& input_file, const std::string& output_file) {
        std::ifstream infile(input_file);
        std::ofstream outfile(output_file);
        std::string line;

        while (std::getline(infile, line)) {
            size_t comma_pos = line.find(',');
            if (comma_pos != std::string::npos) {
                outfile << line.substr(comma_pos + 1) << std::endl; // Печатаем значение времени во втором столбце
            }
        }
    }
};

class TimeUtils {
public:
    static std::string getCurrentDateTimeString() {
        std::time_t now = std::time(nullptr);
        std::tm* local_time = std::localtime(&now);
        std::ostringstream oss;
        oss << std::put_time(local_time, "%Y.%m.%d_%H-%M-%S");
        return oss.str();
    }

    static std::string getFileExtension(const std::string& filename) {
        size_t dot_pos = filename.rfind('.');
        return (dot_pos != std::string::npos) ? filename.substr(dot_pos) : ""; // Возвращает все, что после последней точки
    }
};

class TimestampFileParser {
public:
    static std::vector<Time> readKeyframesFromFile(const std::string& filename) {
        std::ifstream file(filename);
        std::vector<Time> timestamps;
        std::string line;
        while (std::getline(file, line)) {
            Time time = parseTime(line);
            if (time.isValid()) {
                timestamps.push_back(time);
            }
        }
        return timestamps;
    }

    static Time findMaxTimeLessThan(const std::vector<Time>& timestamps, const Time& user_time) {
        Time max_time;
        for (const auto& current_time : timestamps) {
            if (current_time < user_time && current_time > max_time) {
                max_time = current_time;
            }
        }
        return max_time;
    }

private:
    static Time parseTime(const std::string& time_string) {
        int h, m;
        double s;
        char colon1, colon2;
        std::istringstream ss(time_string);
        ss >> h >> colon1 >> m >> colon2 >> s;

        if (ss && colon1 == ':' && colon2 == ':') {
            return Time(h, m, s);
        }
        return Time(); // Возвращаем время по умолчанию (0, 0, 0)
    }
};

class Application {
private:
    std::string input_file;
    std::string keyframe_file;

public:
    Application(const std::string& file) : input_file(file) {
        keyframe_file = input_file + "_keyframes.txt";
    }

    void process(const std::string& search_time_str, const std::string& end_time_str) {
        if (!checkIfFileExists(keyframe_file)) {
            extractKeyframes();
        }

        Time user_time = parseSearchTime(search_time_str);
        auto timestamps = TimestampFileParser::readKeyframesFromFile(keyframe_file);
        Time max_time = TimestampFileParser::findMaxTimeLessThan(timestamps, user_time);

        if (max_time.getSeconds() > 0) { // Используем метод getSeconds()
            handleFoundTime(max_time, end_time_str);
        } else {
            std::cout << "No time found less than " << user_time.toString() << "." << std::endl;
        }
    }

private:
    void extractKeyframes() {
        std::string formatted_keyframe_file = input_file + "_formatted_keyframes.txt";
        if (!FrameExtractor::runFFProbe(input_file, keyframe_file)) {
            throw std::runtime_error("Error running ffprobe.");
        }
        FrameExtractor::formatTimestamps(keyframe_file, formatted_keyframe_file);
        // Удаляем оригинальный файл с ключевыми кадрами
        remove(keyframe_file.c_str());
        // Переименовываем отформатированный файл
        rename(formatted_keyframe_file.c_str(), keyframe_file.c_str());
    }

    Time parseSearchTime(const std::string& search_time_str) {
        int h, m;
        double s;
        char colon1, colon2;
        std::istringstream ss(search_time_str);
        ss >> h >> colon1 >> m >> colon2 >> s;
        return Time(h, m, s);
    }

    void handleFoundTime(Time& max_time, const std::string& end_time_str) {
        max_time.subtract(0.1); // Вычитаем 0.1 секунды
        std::string output_file = generateOutputFilename();
        std::string command = buildFFmpegCommand(max_time, end_time_str, output_file);
        
        if (system(command.c_str()) != 0) {
            throw std::runtime_error("Error running ffmpeg.");
        }

        std::cout << "The largest time less than " << max_time.toString() 
                  << " is " << max_time.toString() << std::endl;
    }

    std::string generateOutputFilename() {
        std::string file_extension = TimeUtils::getFileExtension(input_file);
        std::string current_datetime_suffix = TimeUtils::getCurrentDateTimeString();
        return input_file.substr(0, input_file.size() - file_extension.size()) 
               + "." + current_datetime_suffix + file_extension;
    }

    std::string buildFFmpegCommand(const Time& max_time, const std::string& end_time_str, const std::string& output_file) {
        return "ffmpeg -i \"" + input_file + "\" -map_metadata -1 -map_chapters -1 -avoid_negative_ts make_zero -ss "
               + max_time.toString() + (end_time_str.empty() ? "" : " -to " + end_time_str) + " -c copy \"" + output_file + "\"";
    }

    bool checkIfFileExists(const std::string& filename) {
        std::ifstream file(filename);
        return file.good();
    }
};

int main(int argc, char* argv[]) {
    if (argc < 3) {
        std::cerr << "Usage: " << argv[0] << " <input_file> <time_to_compare> <end_time (optional)>" << std::endl;
        return 1;
    }

    try {
        std::string input_file = argv[1];
        std::string search_time_str = argv[2];
        std::string end_time_str = (argc > 3) ? argv[3] : ""; // Опциональный третий аргумент

        Application app(input_file);
        app.process(search_time_str, end_time_str);
    } catch (const std::runtime_error& e) {
        std::cerr << e.what() << std::endl;
        return 1;
    }

    return 0;
}

Вложения
ffprobe.zip
(16.15 МБ) 49 скачиваний
ffprobe.zip
(16.15 МБ) 49 скачиваний
splitter.zip
(694.27 КБ) 39 скачиваний
splitter.zip
(694.27 КБ) 39 скачиваний
ya
^-^
Сообщения: 2336
Зарегистрирован: 16 дек 2021, 19:56

Re: Сохранить фрагмент из видеофайла (нарезка на фрагменты)

Сообщение ya »

исправлено: условие при котором время начала может быть равно 0

splitter3.cpp

Код: Выделить всё

#include <iostream>
#include <iomanip>
#include <sstream>
#include <vector>
#include <string>
#include <fstream>
#include <cstdlib> // Для system()
#include <algorithm>
#include <ctime>   // Для работы с датой и временем

class Time {
private:
    int hours, minutes;
    double seconds;

public:
    Time(int h = 0, int m = 0, double s = 0.0) : hours(h), minutes(m), seconds(s) {}

    std::string toString() const {
        std::stringstream ss;
        ss << std::setw(2) << std::setfill('0') << hours << ":"
           << std::setw(2) << std::setfill('0') << minutes << ":"
           << std::fixed << std::setprecision(6) << std::setfill('0') << seconds;
        return ss.str();
    }

    bool operator<(const Time& other) const {
        return std::tie(hours, minutes, seconds) < std::tie(other.hours, other.minutes, other.seconds);
    }

    bool operator>(const Time& other) const {
        return std::tie(hours, minutes, seconds) > std::tie(other.hours, other.minutes, other.seconds);
    }

    void subtract(double sec) {
        seconds -= sec;
        while (seconds < 0) {
            seconds += 60;
            minutes--;
        }
        while (minutes < 0) {
            minutes += 60;
            hours--;
        }
        if (hours < 0) {
            hours = minutes = 0;
            seconds = 0.0;
        }
    }

    // Добавим метод для проверки валидности времени
    bool isValid() const {
        return (hours >= 0 && minutes >= 0 && seconds >= 0);
    }

    // Метод для доступа к полю seconds
    double getSeconds() const {
        return seconds;
    }
};

class FrameExtractor {
public:
    static bool runFFProbe(const std::string& input_file, const std::string& output_file) {
        std::string command = "ffprobe -i \"" + input_file + "\" -select_streams v -skip_frame nokey -show_frames " 
                              "-show_entries frame=pkt_pts_time -sexagesimal -print_format csv > \"" + output_file + "\"";
        return system(command.c_str()) == 0; // Возвращает true, если команда выполнена успешно
    }

    static void formatTimestamps(const std::string& input_file, const std::string& output_file) {
        std::ifstream infile(input_file);
        std::ofstream outfile(output_file);
        std::string line;

        while (std::getline(infile, line)) {
            size_t comma_pos = line.find(',');
            if (comma_pos != std::string::npos) {
                outfile << line.substr(comma_pos + 1) << std::endl; // Печатаем значение времени во втором столбце
            }
        }
    }
};

class TimeUtils {
public:
    static std::string getCurrentDateTimeString() {
        std::time_t now = std::time(nullptr);
        std::tm* local_time = std::localtime(&now);
        std::ostringstream oss;
        oss << std::put_time(local_time, "%Y.%m.%d_%H-%M-%S");
        return oss.str();
    }

    static std::string getFileExtension(const std::string& filename) {
        size_t dot_pos = filename.rfind('.');
        return (dot_pos != std::string::npos) ? filename.substr(dot_pos) : ""; // Возвращает все, что после последней точки
    }
};

class TimestampFileParser {
public:
    static std::vector<Time> readKeyframesFromFile(const std::string& filename) {
        std::ifstream file(filename);
        std::vector<Time> timestamps;
        std::string line;
        while (std::getline(file, line)) {
            Time time = parseTime(line);
            if (time.isValid()) {
                timestamps.push_back(time);
            }
        }
        return timestamps;
    }

    static Time findMaxTimeLessThan(const std::vector<Time>& timestamps, const Time& user_time) {
        Time max_time;
        for (const auto& current_time : timestamps) {
            if (current_time < user_time && current_time > max_time) {
                max_time = current_time;
            }
        }
        return max_time;
    }

private:
    static Time parseTime(const std::string& time_string) {
        int h, m;
        double s;
        char colon1, colon2;
        std::istringstream ss(time_string);
        ss >> h >> colon1 >> m >> colon2 >> s;

        if (ss && colon1 == ':' && colon2 == ':') {
            return Time(h, m, s);
        }
        return Time(); // Возвращаем время по умолчанию (0, 0, 0)
    }
};


class Application {
private:
    std::string input_file;
    std::string keyframe_file;

public:
    Application(const std::string& file) : input_file(file) {
        keyframe_file = input_file + "_keyframes.txt";
    }

    void process(const std::string& search_time_str, const std::string& end_time_str) {
        if (search_time_str == "0") {
            // Если second argument is "0", просто вызываем ffmpeg без дополнительных операций
            generateAndRunFFmpegCommand(end_time_str);
            return; // Возвращаемся, чтобы не производить дальнейшие операции
        }

        if (!checkIfFileExists(keyframe_file)) {
            extractKeyframes();
        }

        Time user_time = parseSearchTime(search_time_str);
        auto timestamps = TimestampFileParser::readKeyframesFromFile(keyframe_file);
        Time max_time = TimestampFileParser::findMaxTimeLessThan(timestamps, user_time);

        if (max_time.getSeconds() > 0) {
            handleFoundTime(max_time, end_time_str);
        } else {
            std::cout << "No time found less than " << user_time.toString() << "." << std::endl;
        }
    }

private:
    void extractKeyframes() {
        std::string formatted_keyframe_file = input_file + "_formatted_keyframes.txt";
        if (!FrameExtractor::runFFProbe(input_file, keyframe_file)) {
            throw std::runtime_error("Error running ffprobe.");
        }
        FrameExtractor::formatTimestamps(keyframe_file, formatted_keyframe_file);
        remove(keyframe_file.c_str());
        rename(formatted_keyframe_file.c_str(), keyframe_file.c_str());
    }

    Time parseSearchTime(const std::string& search_time_str) {
        int h, m;
        double s;
        char colon1, colon2;
        std::istringstream ss(search_time_str);
        ss >> h >> colon1 >> m >> colon2 >> s;
        return Time(h, m, s);
    }

    void handleFoundTime(Time& max_time, const std::string& end_time_str) {
        max_time.subtract(0.1);
        std::string output_file = generateOutputFilename();
        std::string command = buildFFmpegCommand(max_time, end_time_str, output_file);
        
        if (system(command.c_str()) != 0) {
            throw std::runtime_error("Error running ffmpeg.");
        }

        std::cout << "The largest time less than " << max_time.toString() 
                  << " is " << max_time.toString() << std::endl;
    }

    void generateAndRunFFmpegCommand(const std::string& end_time_str) {
        std::string output_file = generateOutputFilename();
        std::string command = "ffmpeg -i \"" + input_file + "\" -map_metadata -1 -map_chapters -1 -avoid_negative_ts make_zero -c copy \"" + output_file + "\"";

        if (!end_time_str.empty()) {
            command.insert(command.find("-c copy") - 1, " -to " + end_time_str); // Добавление параметра -to
        }

        if (system(command.c_str()) != 0) {
            throw std::runtime_error("Error running ffmpeg.");
        }

        std::cout << "Command executed successfully: " << command << std::endl;
    }

    std::string generateOutputFilename() {
        std::string file_extension = TimeUtils::getFileExtension(input_file);
        std::string current_datetime_suffix = TimeUtils::getCurrentDateTimeString();
        return input_file.substr(0, input_file.size() - file_extension.size()) 
               + "." + current_datetime_suffix + file_extension;
    }

    std::string buildFFmpegCommand(const Time& max_time, const std::string& end_time_str, const std::string& output_file) {
        return "ffmpeg -i \"" + input_file + "\" -map_metadata -1 -map_chapters -1 -avoid_negative_ts make_zero -ss "
               + max_time.toString() + (end_time_str.empty() ? "" : " -to " + end_time_str) + " -c copy \"" + output_file + "\"";
    }

    bool checkIfFileExists(const std::string& filename) {
        std::ifstream file(filename);
        return file.good();
    }
};

int main(int argc, char* argv[]) {
    if (argc < 3) {
        std::cerr << "Usage: " << argv[0] << " <input_file> <time_to_compare> <end_time (optional)>" << std::endl;
        return 1;
    }

    try {
        std::string input_file = argv[1];
        std::string search_time_str = argv[2];
        std::string end_time_str = (argc > 3) ? argv[3] : "";

        Application app(input_file);
        app.process(search_time_str, end_time_str);
    } catch (const std::runtime_error& e) {
        std::cerr << e.what() << std::endl;
        return 1;
    }

    return 0;
}
Makefile

Код: Выделить всё

# Определяем компилятор и флаги компиляции
CXX = g++
CXXFLAGS = -std=c++11 -Wall -Wextra

# Основной целевой файл
TARGET = splitter

# Исходные файлы
SRCS = splitter3.cpp  # Замените 'main.cpp' на имя вашего файла с кодом

# Объектные файлы
OBJS = $(SRCS:.cpp=.o)

# Правило по умолчанию для сборки
all: $(TARGET)

# Линковка объекта в исполняемый файл
$(TARGET): $(OBJS)
	$(CXX) $(OBJS) -o $(TARGET)

# Правило для компиляции исходников в объектные файлы
%.o: %.cpp
	$(CXX) $(CXXFLAGS) -c $< -o $@

# Правило для очистки
clean:
	rm -f $(OBJS) $(TARGET)

.PHONY: all clean
Вложения
ff_splitter.zip
(680.35 КБ) 41 скачивание
ff_splitter.zip
(680.35 КБ) 41 скачивание
Ответить