如何用C语言将多组仿真结果按时间步对应写入文本文件列中
解决方案:在C语言中对齐仿真结果列或用Python后处理
方法一:先存储所有数据再一次性写入(推荐,逻辑简单)
如果仿真数据量不大,可先将所有时间步和仿真结果存入二维数组,待所有仿真完成后逐行写入文件,确保每行对应同一时间步的所有仿真结果。
示例代码
#include <stdio.h> #include <stdlib.h> int main() { int nsim = 3; // 仿真次数 int timesteps = 5; // 时间步数(含初始时刻t=0) double h = 1.0; // 时间步长 double x_0 = 0.001000; // 初始值 // 分配二维内存:行=时间步,列=时间+各仿真结果 double **data = malloc(timesteps * sizeof(double*)); if (!data) { printf("内存分配失败\n"); return 1; } for (int i = 0; i < timesteps; i++) { data[i] = malloc((nsim + 1) * sizeof(double)); if (!data[i]) { printf("内存分配失败\n"); return 1; } data[i][0] = h * i; // 填充时间列 } // 执行所有仿真,填充数据 for (int m = 0; m < nsim; m++) { data[0][m+1] = x_0; // 初始时刻值 for (int t = 1; t < timesteps; t++) { // 替换为你的实际计算逻辑,这里用模拟值示例 double x = data[t-1][m+1] + 0.0001 * (m+1); data[t][m+1] = x; } printf("Simulation %d completed\n", m+1); } // 写入文件 FILE *f1 = fopen("x.txt", "w"); if (!f1) { printf("文件打开失败\n"); return 1; } // 写入表头 fprintf(f1, "Time"); for (int m = 0; m < nsim; m++) { fprintf(f1, "\tSim %d", m+1); } fprintf(f1, "\n"); // 逐行写入时间+各仿真结果 for (int t = 0; t < timesteps; t++) { fprintf(f1, "%.2lf", data[t][0]); for (int m = 0; m < nsim; m++) { fprintf(f1, "\t%lf", data[t][m+1]); } fprintf(f1, "\n"); } fclose(f1); // 释放内存 for (int i = 0; i < timesteps; i++) { free(data[i]); } free(data); return 0; }
方法二:文件定位追加(适合大内存占用场景)
若仿真数据量极大无法全部存入内存,可在第一次仿真时写入时间和第一列结果,后续仿真通过文件定位逐行追加到对应时间步的行末尾。
示例代码
#include <stdio.h> #include <stdlib.h> int main() { int nsim = 3; int timesteps = 5; double h = 1.0; double x_0 = 0.001000; // 第一次仿真:写入时间+Sim1结果 FILE *f1 = fopen("x.txt", "w"); if (!f1) { printf("文件打开失败\n"); return 1; } fprintf(f1, "Time\tSim 1\n"); fprintf(f1, "%.2lf\t%lf\n", 0.0, x_0); for (int t = 1; t < timesteps; t++) { double x = x_0 + 0.0001 * 1; // 替换为你的计算逻辑 fprintf(f1, "%.2lf\t%lf\n", h*t, x); } fclose(f1); printf("Simulation 1 completed\n"); // 后续仿真:逐行追加结果 for (int m = 1; m < nsim; m++) { f1 = fopen("x.txt", "r+"); if (!f1) { printf("文件打开失败\n"); return 1; } // 更新表头,追加新仿真列名 char header[256]; fgets(header, sizeof(header), f1); fseek(f1, ftell(f1)-1, SEEK_SET); // 定位到表头换行符前 fprintf(f1, "\tSim %d\n", m+1); // 逐行处理每个时间步 for (int t = 0; t < timesteps; t++) { char line[256]; fgets(line, sizeof(line), f1); long line_end_pos = ftell(f1) - 1; // 定位到当前行换行符前 fseek(f1, line_end_pos, SEEK_SET); // 计算当前仿真的x值,替换为你的逻辑 double x = (t == 0) ? x_0 : x_0 + 0.0001 * (m+1); fprintf(f1, "\t%lf\n", x); } fclose(f1); printf("Simulation %d completed\n", m+1); } return 0; }
方法三:Python后处理现有文件
若不想修改C代码,可使用Python读取当前生成的分块文件,重新整理为对齐的列格式:
示例Python代码
# 读取原始分块文件 with open('x.txt', 'r') as f: lines = [line.strip() for line in f.readlines() if line.strip()] # 拆分文件内容为多个仿真块 blocks = [] current_block = [] for line in lines: if line.startswith("Time"): # 跳过表头(如果存在) continue current_block.append(line) # 按时间步数拆分块(示例中为4个时间步) if len(current_block) == 4: blocks.append(current_block) current_block = [] if current_block: blocks.append(current_block) # 提取时间列(从第一个块) time_col = [line.split('\t')[0] for line in blocks[0]] # 提取各仿真数据列 sim_cols = [] for idx, block in enumerate(blocks): if idx == 0: # 第一个块包含时间+Sim1数据 sim_cols.append([line.split('\t')[1] for line in block]) else: # 后续块只有仿真数据 sim_cols.append(block) # 写入对齐后的新文件 with open('aligned_x.txt', 'w') as f: # 写表头 f.write('Time\t' + '\t'.join([f'Sim {i+1}' for i in range(len(sim_cols))]) + '\n') # 逐行写入对齐数据 for i in range(len(time_col)): line_parts = [time_col[i]] + [col[i] for col in sim_cols] f.write('\t'.join(line_parts) + '\n')
内容的提问来源于stack exchange,提问作者Ander Gabarrus
相关产品推荐
相关产品推荐

