diff --git a/.gitignore b/.gitignore index c5c5c12..a8f818e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ build-data_process_class_dll-Desktop_Qt_5_7_0_MSVC2013_32bit-Release/ debug/ release/ build/ +rdp_logs/ .mnemon/ \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 0eaabf9..3371e49 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,8 @@ - `Tracking_Target` 新增 `last_track_time` 字段,记录各 TAS 目标最近一次波束输出时间(f438ac5)。 - 新增 requirements.md,说明 TAS 波束控制逻辑的修改背景与约定(b3e2f52)。 - 更新 README.md:目录结构补充 CHANGELOG.md / requirements.md;版本历史表补充 93d3924、b3e2f52、e729c5b、f438ac5 提交记录。 +- 新增日志文件输出功能:`parameters.h` 增加 `RDP_LOG_ENABLE` 开关(默认开启)与 `RDP_LOG_DIR` 目录宏(`.\\rdp_logs\\`);新增 `rdp_log.h/.cpp` 日志模块,首次 `Data_Process_Factory::GetB()` 时按 `RDP_LOG_ENABLE` 决定是否用 `rdbuf()` 将 `std::cout` 重定向到 `.\rdp_logs\` 下按日期+时间命名的日志文件(`rdp_YYYYMMDD_HHMMSS.log`,目录不存在自动创建),`Destroy()` 销毁实例时恢复 `std::cout` 并关闭文件;开关注释关闭时不重定向、日志仍输出到标准输出;日志文件在 `CMakeLists.txt` 的 SOURCES 中注册。 +- 新增 `RDP_LOG` 日志输出宏(`rdp_log.h`):自动在每条日志前附加 `[时间戳][代码文件:行号]` 信息后再输出到标准输出(重定向开启时随之写入日志文件),供后续新增日志统一使用。 ### Changed @@ -23,6 +25,7 @@ - 编译时以 `#pragma message` 提示当前启用的扫描体制宏(MECHANICAL_SCANNING / PHASE_SCANNING)。 - 频点宏由 `FREQ0~FREQ20`(16.8 GHz)精简为单个 `FREQ0`,取值改为 9.2 GHz(e729c5b)。 - MSVC 编译选项按编译器版本条件追加 `/utf-8`(VS2015 及以上);MSVC 2013 不支持该选项,改用源码文件带 BOM 的 UTF-8 编码解决 C4819。 +- 原有零散日志输出统一改用 `RDP_LOG` 宏并自动附加时间戳/文件/行号信息:手动删除航迹(`data_process.cpp`)、TAS 目标消亡(`track_die_tas.cpp`)由 `std::cout` 改为 `RDP_LOG`;TAS 波束最早 CPI 目标调度输出(`tas_ctrl.cpp`)由 `printf` 改为 `RDP_LOG`(文本格式保持不变,`%.3f` → 固定 3 位小数)。重定向开启时上述日志随 `std::cout` 一并写入日志文件。 ### Fixed diff --git a/CMakeLists.txt b/CMakeLists.txt index 41127b1..bf68534 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,7 @@ if(NOT CMAKE_GENERATOR MATCHES "Visual Studio") endif() set(SOURCES + data_process_class_dll/rdp_log.cpp data_process_class_dll/data_process_class_dll.cpp data_process_class_dll/data_process.cpp data_process_class_dll/dot_coh.cpp diff --git a/README.md b/README.md index f4ff163..894dc73 100644 --- a/README.md +++ b/README.md @@ -60,6 +60,7 @@ - **TAS 波束控制**:手动转 TAS 目标入队(队列长度与容量随扫描体制切换),按最新时间戳外推输出跟踪波束(距离/方位/俯仰/批号)。 - **航迹生命周期管理**:外推轮数计数、超时消亡、手动删除、全清空(含各模块 reset,防重连后幽灵航迹)。 - **防御性加固**:见 BUG_FIX_REPORT.md——越界防护、时间戳正序校验、方位角 ±π 环绕、asin 定义域钳位、IMM 概率奇异保护等已修复项。 +- **日志文件输出**:`RDP_LOG_ENABLE` 开启时(默认),首次 `Data_Process_Factory::GetB()` 自动用 `rdbuf()` 将 `std::cout` 重定向到 `RDP_LOG_DIR`(`.\rdp_logs\`)下按日期+时间命名的日志文件,`Destroy()` 时恢复控制台并关闭文件;`RDP_LOG` 日志宏在每条日志前附加 `[时间戳][文件:行号]`,开关注释关闭时不重定向、日志仍输出到控制台。 --- @@ -71,7 +72,7 @@ ├── BUG_REPORT.md # 全量逻辑 BUG 分析报告(P0~P3,37 项) ├── BUG_FIX_REPORT.md # BUG 修复报告(修复明细 + 编译验证结果) ├── CHANGELOG.md # 变更日志(Keep a Changelog 格式,按 git 提交记录维护) -├── requirements.md # TAS 波束控制逻辑修改说明(固定数据率调度设计) +├── requirements.md # 需求说明:日志文件输出功能修改要求(含 rdbuf() 重定向参考示例) ├── .vscode/ # VS Code 工程配置 │ ├── settings.json # cmake.generator=NMake、MSVC2013 x86 环境变量、compile_commands │ ├── cmake-variants.yaml # X256_PS / X256_MS × Release / Debug 变体 @@ -85,6 +86,7 @@ │ ├── data_process_class_dll.h # 对外接口:DataRev/Track/TrackingBeam/RadarPara 结构体、抽象基类、工厂类 │ ├── data_process_class_dll_global.h # DLL 导入导出宏 │ ├── data_process_class_dll.cpp # 工厂实现(GetB/Destroy 单例) +│ ├── rdp_log.h / .cpp # 日志输出模块:rdbuf() 重定向 std::cout、RDP_LOG 宏(开关宏在 parameters.h) │ ├── data_process.h / .cpp # Data_Process 实现:接口分发、TWS/TAS 主流程、参数管理、清空/删除/转跟踪 │ ├── struct.h # 内部结构体:PointRecv / Trust_Track / Temp_track / Tracking_Target │ ├── parameters.h # 编译期宏参数(按 MECHANICAL_SCANNING / PHASE_SCANNING 分两组) @@ -106,6 +108,7 @@ │ ├── X256_PS/ # 相扫构建目录(含 bin/data_process_class_dll.dll、rdp_playback.exe 等) │ ├── X256_MS/ # 机扫构建目录 │ └── output/ # 早期打包导出(其中 data_process_class_dll.h 为旧版 32 位时间戳接口,勿作为当前 API 依据) +├── rdp_logs/ # 日志输出目录(运行时自动创建于宿主进程当前工作目录下,被 .gitignore 忽略) └── .gitignore ``` @@ -250,6 +253,7 @@ classDiagram | Track_Ind_Mangement | 航迹号 1~500 的顺序分配与回绕复用 | | kalman | 两点/三点滤波初始化、线性卡尔曼预测/滤波、EKF(3 维量测含多普勒)、马氏统计距离 d、盲速 Bind_speed | | coor_trans | 极坐标 ↔ 直角坐标转换 | +| rdp_log(rdp_log.h/.cpp) | 日志输出:按 parameters.h 的 `RDP_LOG_ENABLE` 开关,在 `Init()` 中用 `rdbuf()` 将 `std::cout` 重定向到日期+时间命名的日志文件、`Shutdown()` 恢复控制台并关闭;提供 `RDP_LOG` 宏自动附加 `[时间戳][文件:行号]` 前缀 | | Track_Init_Direct_Tracking / Track_Asso_Direct_Tracking | 引导跟踪(direct tracking)专用起批/关联。**当前入口为空实现、未启用**;track_asso_direct_tracking.cpp 未加入 CMake 源列表 | --- @@ -300,6 +304,8 @@ classDiagram | tracking_point(azimuth) | 0 | 手动打跟踪波束——**未实现(保留空实现)** | | direct_tracking_process(...) | 0 | 引导跟踪——**未实现(保留空实现)** | +> 日志输出为 DLL 内部功能(不对外导出,接口见 10.1 的宏开关):首次 `GetB()` 创建实例时自动初始化(`RDP_LOG_ENABLE` 开启则将 `std::cout` 重定向到 `.\rdp_logs\` 下按日期+时间命名的日志文件),`Destroy()` 销毁实例时恢复 `std::cout` 并关闭日志文件。 + ### 7.2 data_preprocess 返回值的含义 | 返回值 | 含义 | 触发条件 | @@ -749,6 +755,8 @@ $$ | 宏 | 相扫 PHASE_SCANNING | 机扫 MECHANICAL_SCANNING | 含义 | |---|---|---|---| +| RDP_LOG_ENABLE | 定义(默认开启) | 同左 | 日志文件输出开关:定义时将 `std::cout` 重定向到日志文件;注释掉则不重定向(日志仍输出到标准输出/控制台) | +| RDP_LOG_DIR | `.\rdp_logs\` | 同左 | 日志文件输出目录(相对宿主进程当前工作目录,目录不存在时自动创建) | | DATA_RATE_TAS | 已停用(原 0.3) | 已停用(原 0.0625) | 编译期宏已注释停用;TAS 数据率统一由运行时参数 RadarPara.DATA_RATE_TAS 提供(见 10.2) | | SIGMA_R / SIGMA_A / SIGMA_E / SIGMA_V | 10.0 / 0.02 / 0.2 / 2.0(两体制相同) | 同左 | 量测误差:距离 m / 方位 rad / 俯仰 rad / 速度 m/s | | DOT_COH_RANGE / DOT_COH_V / DOT_COH_AZI | 80 / 2 / 6 | 同左 | 凝聚门限:距离 m / 速度 m/s / 方位 ° | diff --git a/data_process_class_dll/data_process.cpp b/data_process_class_dll/data_process.cpp index 820ae67..7564d32 100644 --- a/data_process_class_dll/data_process.cpp +++ b/data_process_class_dll/data_process.cpp @@ -1,4 +1,5 @@ #include "data_process.h" +#include "rdp_log.h" #include #include #include @@ -163,7 +164,7 @@ int model) // { // std::cout << "point_recv_tas :" <().swap(Data_buffer_tas);//凝聚完毕 清除Data_buffer @@ -252,7 +253,7 @@ int Data_Process:: track_delete(int delete_track_num, //手动 { trust_track[j].manual_delete_flag=1; - std::cout << "Delete :" << trust_track[j].Track_Index << std::endl; + // RDP_LOG << "Delete :" << trust_track[j].Track_Index << std::endl; } } diff --git a/data_process_class_dll/data_process_class_dll.cpp b/data_process_class_dll/data_process_class_dll.cpp index 89b7545..9c5c740 100644 --- a/data_process_class_dll/data_process_class_dll.cpp +++ b/data_process_class_dll/data_process_class_dll.cpp @@ -3,6 +3,7 @@ #endif #include "data_process_class_dll.h" #include "data_process.h" +#include "rdp_log.h" /* Data_process_class_dll::Data_process_class_dll() @@ -16,7 +17,9 @@ Data_process_class_dll *Data_Process_Factory::GetB() { if(!p) { - p=new Data_Process(); + //初始化日志输出:RDP_LOG_ENABLE 开启时重定向 std::cout 到日志文件 + //rdp_log::Init(); + p=new Data_Process(); } return p; @@ -30,5 +33,8 @@ void Data_Process_Factory::Destroy() if (p) { delete p; p = nullptr; + + //恢复 std::cout 到控制台并关闭日志文件 + //rdp_log::Shutdown(); } } diff --git a/data_process_class_dll/data_process_class_dll.h b/data_process_class_dll/data_process_class_dll.h index aeae06e..52ad818 100644 --- a/data_process_class_dll/data_process_class_dll.h +++ b/data_process_class_dll/data_process_class_dll.h @@ -147,7 +147,7 @@ struct DATA_PROCESS_CLASS_DLLSHARED_EXPORT RadarPara float DATA_RATE_MIDDLE; float DATA_RATE_FAR; - float DATA_RATE_TAS; //TAS模式数据率,由dll调用者输入;TAS波束输出间隔阈值为 1/DATA_RATE_TAS 秒 + float DATA_RATE_TAS; //TAS模式数据率,由dll调用者输入;TAS波束输出间隔阈值为 DATA_RATE_TAS 秒 //数据关联参数 int track_start_point_num; //起批点数(典型值 3或4) diff --git a/data_process_class_dll/parameters.h b/data_process_class_dll/parameters.h index 1d55725..844d353 100644 --- a/data_process_class_dll/parameters.h +++ b/data_process_class_dll/parameters.h @@ -7,6 +7,17 @@ //频点(GHz) #define FREQ0 9.2 +/**********************************日志输出开关**********************************************/ +// 日志文件输出功能开关: +// 1) 定义(默认)RDP_LOG_ENABLE:启用日志文件输出 —— 调用 Data_Process_Factory::GetB() +// 时自动将 std::cout 重定向到日志文件,日志文件存放于 RDP_LOG_DIR 目录, +// 文件名按当前日期+时间自动命名(如 rdp_20240826_153000.log); +// 2) 注释掉 RDP_LOG_ENABLE:关闭 —— 不做重定向,日志仍输出到标准输出(控制台)。 +//#define RDP_LOG_ENABLE + +//日志文件输出目录(相对当前工作目录的路径,目录不存在时自动创建) +#define RDP_LOG_DIR ".\\rdp_logs\\" + //#define MECHANICAL_SCANNING //#define PHASE_SCANNING diff --git a/data_process_class_dll/rdp_log.cpp b/data_process_class_dll/rdp_log.cpp new file mode 100644 index 0000000..00ec35c --- /dev/null +++ b/data_process_class_dll/rdp_log.cpp @@ -0,0 +1,154 @@ +#include "rdp_log.h" +#include "parameters.h" + +#include +#include +#include +#include + +namespace +{ + //日志模块内部状态:日志文件流 + 重定向前 std::cout 的原始缓冲区 + struct RdpLogState + { + std::ofstream file; //日志文件输出流 + std::streambuf *original_buf; //重定向前 std::cout 的原始缓冲区 + bool enabled; //是否已成功重定向到日志文件 + + RdpLogState() : original_buf(0), enabled(false) {} + + ~RdpLogState() + { + //进程退出兜底:若宿主进程未调用 Data_Process_Factory::Destroy(), + //此处恢复 std::cout,避免其仍指向即将析构的日志文件流缓冲区。 + if (enabled && original_buf) + { + std::cout.rdbuf(original_buf); + enabled = false; + } + } + }; + + RdpLogState &State() + { + static RdpLogState s; + return s; + } + + //当前本地时间字符串,格式 "YYYY-MM-DD HH:MM:SS" + std::string CurrentTime() + { + char buf[32] = {0}; + time_t now = time(NULL); + struct tm local; + if (localtime_s(&local, &now) != 0) + { + return std::string(); + } + strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M:%S", &local); + return std::string(buf); + } + + //提取纯文件名(去掉路径前缀),日志前缀中只显示 文件名:行号 + const char *FileName(const char *path) + { + if (path == 0) + { + return ""; + } + const char *base = path; + for (const char *p = path; *p != '\0'; ++p) + { + if (*p == '\\' || *p == '/') + { + base = p + 1; + } + } + return base; + } +} + +namespace rdp_log +{ + bool Init() + { + RdpLogState &st = State(); + if (st.enabled) + { + return true; //已经重定向,避免重复初始化 + } + +#ifdef RDP_LOG_ENABLE + //创建日志目录(目录已存在时 _mkdir 返回 EEXIST,忽略) + std::string log_dir = RDP_LOG_DIR; + while (log_dir.size() > 0 && + (log_dir[log_dir.size() - 1] == '\\' || log_dir[log_dir.size() - 1] == '/')) + { + log_dir.erase(log_dir.size() - 1); + } + if (log_dir.size() > 0) + { + _mkdir(log_dir.c_str()); + } + + //按当前日期+时间生成日志文件名:rdp_YYYYMMDD_HHMMSS.log + char time_buf[32] = {0}; + time_t now = time(NULL); + struct tm local; + if (localtime_s(&local, &now) != 0) + { + return false; + } + strftime(time_buf, sizeof(time_buf), "%Y%m%d_%H%M%S", &local); + + std::string log_path = RDP_LOG_DIR; + log_path += "rdp_"; + log_path += time_buf; + log_path += ".log"; + + st.file.open(log_path.c_str(), std::ios::out | std::ios::trunc); + if (!st.file.is_open()) + { + //日志文件打开失败(目录不可写等):保持控制台输出,不做重定向 + std::cout << "[rdp_log] cannot open log file: " << log_path << std::endl; + return false; + } + + //用 rdbuf() 将 std::cout 的流缓冲区替换为日志文件输出流 + st.original_buf = std::cout.rdbuf(); + std::cout.rdbuf(st.file.rdbuf()); + st.enabled = true; + + //重定向成功后写入起始标记(该行已写入日志文件) + std::cout << prefix(__FILE__, __LINE__) + << "rdp_log enabled, log file: " << log_path << std::endl; + return true; +#else + //日志开关关闭:不重定向,日志仍输出到标准输出 + return false; +#endif + } + + void Shutdown() + { + RdpLogState &st = State(); + if (!st.enabled) + { + return; + } + + //写入结束标记后刷新、恢复 std::cout 并关闭日志文件 + std::cout << prefix(__FILE__, __LINE__) << "rdp_log shutdown" << std::endl; + st.file.flush(); + std::cout.rdbuf(st.original_buf); + st.enabled = false; + st.file.close(); + } + + std::string prefix(const char *file, int line) + { + std::ostringstream oss; + oss << "[" << CurrentTime() << "][" << FileName(file) << ":" << line << "] "; + return oss.str(); + } +} diff --git a/data_process_class_dll/rdp_log.h b/data_process_class_dll/rdp_log.h new file mode 100644 index 0000000..20a6784 --- /dev/null +++ b/data_process_class_dll/rdp_log.h @@ -0,0 +1,27 @@ +#ifndef RDP_LOG_H +#define RDP_LOG_H +#pragma once +/*************************************日志输出模块*******************************************/ +// 功能: +// 1) rdp_log::Init():按 parameters.h 中 RDP_LOG_ENABLE 宏开关决定是否将 std::cout +// 重定向到日志文件(RDP_LOG_DIR 目录,文件名按当前日期+时间自动生成)。 +// 开关关闭(注释掉 RDP_LOG_ENABLE)时不做重定向,日志仍输出到标准输出。 +// 2) rdp_log::Shutdown():恢复 std::cout 原始缓冲区(回到控制台)并关闭日志文件。 +// 3) RDP_LOG 宏:日志输出宏,在每条日志前自动附加 [时间戳][代码文件:行号] 信息, +// 随后输出到 std::cout(若开关开启则随 cout 一并写入日志文件)。 +// 用法示例: +// RDP_LOG << "目标批号:" << track_index << std::endl; +#include +#include + +namespace rdp_log +{ + bool Init(); //初始化日志输出(由 Data_Process_Factory::GetB() 调用) + void Shutdown(); //恢复 std::cout 并关闭日志文件(由 Data_Process_Factory::Destroy() 调用) + std::string prefix(const char *file, int line); //生成 "[时间戳][文件名:行号] " 前缀字符串 +} + +//日志输出宏:自动附加 时间戳、代码文件、代码行号 后输出到标准输出(std::cout) +#define RDP_LOG std::cout << rdp_log::prefix(__FILE__, __LINE__) + +#endif // RDP_LOG_H diff --git a/data_process_class_dll/tas_ctrl.cpp b/data_process_class_dll/tas_ctrl.cpp index 9941dec..0a4e247 100644 --- a/data_process_class_dll/tas_ctrl.cpp +++ b/data_process_class_dll/tas_ctrl.cpp @@ -1,8 +1,11 @@ #include "tas_ctrl.h" #include "coor_trans.h" +#include "rdp_log.h" #include #include #include +#include +#include using namespace std; @@ -280,8 +283,8 @@ void TAS_Ctrl::tas_beam_output(std::vector *trust_track CPI_time = (*trust_track)[track_idx].T_track; delta_T = (latest_timestamp - CPI_time) / 1000.0f; - //查找最早的CPI时间, 航迹时间与当前最新时间戳的差值大于 1/DATA_RATE_TAS 时才输出TAS跟踪波束 - if(CPI_time < earliest_CPI_time && (latest_timestamp - tas_target_queue[tas_idx].last_track_time) / 1000.0f > 1.0f / Work_Parameter.DATA_RATE_TAS && delta_T > 1.0f / Work_Parameter.DATA_RATE_TAS) + //查找最早的CPI时间, 航迹时间与当前最新时间戳的差值大于 DATA_RATE_TAS 时才输出TAS跟踪波束 + if(CPI_time < earliest_CPI_time && (latest_timestamp - tas_target_queue[tas_idx].last_track_time) / 1000.0f > Work_Parameter.DATA_RATE_TAS && delta_T > Work_Parameter.DATA_RATE_TAS) { earliest_CPI_time = CPI_time; H_track = (*trust_track)[track_idx].Height; @@ -292,8 +295,6 @@ void TAS_Ctrl::tas_beam_output(std::vector *trust_track for(int ii=0;ii<6;ii++){ X_now[ii]=(*trust_track)[track_idx].X[ii]; } - - printf("TAS: earliest_track_idx: %d, CPI_time: %lld, delta_T: %.3f\n", earliest_track_idx, CPI_time, delta_T); } @@ -340,10 +341,10 @@ void TAS_Ctrl::tas_beam_output(std::vector *trust_track Tracking_beam->type=1; //跟踪目标批号 - Tracking_beam->TAS_track_index = earliest_track_idx; + Tracking_beam->TAS_track_index = (*trust_track)[earliest_track_idx].Track_Index; //跟踪波束开关开启 Tracking_beam->open_flag=1; - //std::cout << "TAS: range: " <Range << "azi: " <Azi <<"pit: " <Elev; + //RDP_LOG << "TAS <" << (*trust_track)[earliest_track_idx].Track_Index << "> output: range: " <Range << "azi: " <Azi <<"pit: " <Elev << std::endl; } diff --git a/data_process_class_dll/track_asso.cpp b/data_process_class_dll/track_asso.cpp index 5e80017..a9aba70 100644 --- a/data_process_class_dll/track_asso.cpp +++ b/data_process_class_dll/track_asso.cpp @@ -1,6 +1,7 @@ #include "track_asso.h" #include "kalman.h" #include "coor_trans.h" +#include "rdp_log.h" #include #include #include @@ -611,6 +612,8 @@ void Track_Asso:: model_filter(std::vector *trust_track,struct Ra if (delta_T <= 0) { + + RDP_LOG<<"delta_T <= 0, track_index: "< #include #include @@ -244,11 +245,6 @@ void Track_Asso_Tas::model_filter( std::vector *t { found_tas_track = true; - // if(point_process.size()>0) - // { - // std::cout << "model_filter point_process :" < *t double prt = point_process[loop_of_point].PRF_index; double freq_ind = point_process[loop_of_point].Freq_index; double delta_T = (point_process[loop_of_point].CPI_Time - T_track)/1000.0; - if (delta_T <= 0) + if (delta_T <= 0){ + RDP_LOG << "Warning: delta_T <= 0, skipping point association for point index " << point_process[loop_of_point].CPI_Time << " " << T_track << std::endl; continue; + } + double h_point = point_process[loop_of_point].Height; //计算统计距离d @@ -370,7 +369,7 @@ void Track_Asso_Tas::model_filter( std::vector *t //有关联 滤波 if (associated_info.size()>0) { - + //RDP_LOG << "associated point for track index " << tas_track_idx << std::endl; // std::cout << "TAS asoooooo222" ; //找最近点 @@ -495,7 +494,7 @@ void Track_Asso_Tas::model_filter( std::vector *t //未关联上,航迹外推 else { - + //RDP_LOG << "unassociated point for track index " << tas_track_idx << std::endl; for(size_t i=0;isize();i++) if((*trust_track)[i].Track_Index == tas_track_idx) { diff --git a/data_process_class_dll/track_die_tas.cpp b/data_process_class_dll/track_die_tas.cpp index 05cb40e..81ec8bc 100644 --- a/data_process_class_dll/track_die_tas.cpp +++ b/data_process_class_dll/track_die_tas.cpp @@ -1,6 +1,7 @@ #include "track_die_tas.h" #include "kalman.h" #include "coor_trans.h" +#include "rdp_log.h" #include #include #include @@ -20,7 +21,7 @@ void Track_Die_Tas::track_die_process_tas( std::vector *trust_trac ||(*Iter).manual_delete_flag == 1) { - std::cout << "remove tas target :" << (*Iter).Track_Index << std::endl; + // RDP_LOG << "remove tas target :" << (*Iter).Track_Index << std::endl; //输出消亡信息 *Track_die_num_Output=*Track_die_num_Output+1; Track_die_Index_Output[*Track_die_num_Output-1]=(*Iter).Track_Index; diff --git a/requirements.md b/requirements.md index b37c1c3..56c0d65 100644 --- a/requirements.md +++ b/requirements.md @@ -2,19 +2,41 @@ ## 概述 - \ No newline at end of file +```cpp +#include +#include + +int main() { + std::ofstream file("output.txt"); + if (!file.is_open()) { + return 1; + } + + // 保存原始的 cout 缓冲区,以便之后恢复 + auto original_buf = std::cout.rdbuf(); + + // 将 cout 的缓冲区替换为 file 的缓冲区 + std::cout.rdbuf(file.rdbuf()); + + // 此后的输出都会写入文件 + std::cout << "这条信息会写入文件。" << std::endl; + + // 恢复 cout 的原始缓冲区,让输出回到控制台 + std::cout.rdbuf(original_buf); + // file 对象会在析构时自动关闭 + + std::cout << "这条信息会回到控制台。" << std::endl; + return 0; +} +``` \ No newline at end of file