C语言含多变量与数字格式符的CSV写入优化方法咨询
简化冗长fprintf的高效实现方案
针对你需要输出大量变量到CSV、且后续可能扩展的场景,以下两种内存高效的方案可以大幅简化代码,避免重复的格式符和参数:
方案1:使用宏封装重复的打印逻辑
利用预编译宏把重复的%.*E格式和对应的dig参数封装起来,减少代码冗余:
#define PRINT_CSV_E(fp, val) fprintf(fp, "%.*E,", dig, val) #define PRINT_CSV_E_LAST(fp, val) fprintf(fp, "%.*E\n", dig, val) // 最后一个字段无逗号并换行 int dig = 4; for(k = 0; k < cfg_ptr->nprt; k++){ /*normalize output*/ en_norm = en[k]*norm_factor; en0_norm = en0[k]*norm_factor; mu = rmu[k]*norm_factor; mu0 = rmu0[k]*norm_factor; // 先打印第一个int类型的otp[k] fprintf(ofp, "%d,", otp[k]); // 依次打印浮点变量 PRINT_CSV_E(ofp, thet[k]); PRINT_CSV_E(ofp, zet[k]); PRINT_CSV_E(ofp, ptch[k]); PRINT_CSV_E(ofp, pol[k]); PRINT_CSV_E(ofp, rho[k]); PRINT_CSV_E(ofp, mu); PRINT_CSV_E(ofp, en_norm); PRINT_CSV_E(ofp, rhol[k]); PRINT_CSV_E(ofp, pphi[k]); PRINT_CSV_E(ofp, xflr[k]); PRINT_CSV_E(ofp, zflr[k]); PRINT_CSV_E(ofp, thet0[k]); PRINT_CSV_E(ofp, zet0[k]); PRINT_CSV_E(ofp, ptch0[k]); PRINT_CSV_E(ofp, pol0[k]); PRINT_CSV_E(ofp, rho0[k]); PRINT_CSV_E(ofp, mu0); PRINT_CSV_E(ofp, en0_norm); PRINT_CSV_E(ofp, rhol0[k]); PRINT_CSV_E(ofp, pphi0[k]); PRINT_CSV_E(ofp, xflr0[k]); PRINT_CSV_E_LAST(ofp, zflr0[k]); // 最后一个字段 }
优点:实现简单,无额外内存开销,编译期展开不影响运行效率;后续新增变量只需添加一行PRINT_CSV_E调用即可。
方案2:数组遍历批量打印
把所有要输出的浮点变量地址存入临时数组,通过循环批量打印,进一步减少重复代码,扩展性更强:
int dig = 4; for(k = 0; k < cfg_ptr->nprt; k++){ /*normalize output*/ en_norm = en[k]*norm_factor; en0_norm = en0[k]*norm_factor; mu = rmu[k]*norm_factor; mu0 = rmu0[k]*norm_factor; // 定义要打印的浮点变量数组(栈上临时存储,内存开销极小) double* csv_vars[] = { &thet[k], &zet[k], &ptch[k], &pol[k], &rho[k], &mu, &en_norm, &rhol[k], &pphi[k], &xflr[k], &zflr[k], &thet0[k], &zet0[k], &ptch0[k], &pol0[k], &rho0[k], &mu0, &en0_norm, &rhol0[k], &pphi0[k], &xflr0[k], &zflr0[k] }; int var_count = sizeof(csv_vars)/sizeof(csv_vars[0]); // 打印第一个int字段 fprintf(ofp, "%d,", otp[k]); // 批量打印前var_count-1个变量(带逗号) for(int i=0; i<var_count-1; i++){ fprintf(ofp, "%.*E,", dig, *csv_vars[i]); } // 打印最后一个变量(无逗号,换行) fprintf(ofp, "%.*E\n", dig, *csv_vars[var_count-1]); }
优点:后续新增变量只需在csv_vars数组中添加对应的地址,无需修改打印逻辑;循环打印的方式让代码更整洁,适合变量数量较多的场景。
注意:数组是栈上创建的临时对象,每次循环都会销毁,内存占用可以忽略,完全符合内存高效的要求。
内容的提问来源于stack exchange,提问作者Choop
相关产品推荐
相关产品推荐

