C++创建日志文件报错:Invalid parameter passed to C runtime function
问题根源与修复方案
你的代码遇到两个关键问题,导致文件创建失败并触发那个烦人的运行时错误:
1. 文件名包含系统非法字符
你在fopen里用的是QDateTime::currentDateTime().toString()的默认格式,这个格式生成的字符串类似Thu Jan 15 12:21:50 2018——注意里面的冒号(:),这是Windows文件系统明确禁止的文件名字符,直接导致fopen没法创建文件。而你std::cout打印的是指定了"yyyy-MM-dd hh.mm.ss"格式的字符串(用点代替了冒号),这是合法的,但fopen里根本没用到这个正确格式!
2. 临时对象的生命周期陷阱
表达式(QDateTime::currentDateTime().toString() + ".txt").toStdString()生成的是一个临时std::string对象,当你调用c_str()拿到指针后,这个临时对象会立刻被销毁,指针指向的内存变成无效的垃圾内存。fopen接收到这个无效指针,自然就抛出Invalid parameter passed to C runtime function错误了。
修复后的代码
// 先生成合法的文件名(和你打印的格式保持一致) QString logFileName = QDateTime::currentDateTime().toString("yyyy-MM-dd hh.mm.ss") + ".txt"; // 把QString转成std::string并保存为变量,延长它的生命周期 std::string stdLogName = logFileName.toStdString(); // 用这个变量的c_str()来打开文件,确保指针有效 FILE* smartcutLogFile = fopen(stdLogName.c_str(), "w+t"); // 一定要检查文件是否成功打开,避免后续操作崩溃 if (smartcutLogFile != nullptr) { std::cout << logFileName.toStdString().c_str() << std::endl; fprintf(smartcutLogFile, "D1: %f\n D2: %f\n E2: %f\n E3: %f\n E4: %f\n Z: %f\n", D1, D2, E2, E3, E4, Z_EDGE); fclose(smartcutLogFile); } else { std::cerr << "Failed to create log file: " << stdLogName << std::endl; }
更贴合Qt的优化方案
既然你用的是Qt,不如直接用Qt自带的QFile和QTextStream来处理文件,这样能避免C标准库的字符串生命周期问题,还能更好地适配Qt的生态:
QString logFileName = QDateTime::currentDateTime().toString("yyyy-MM-dd hh.mm.ss") + ".txt"; QFile logFile(logFileName); if (logFile.open(QIODevice::WriteOnly | QIODevice::Text)) { QTextStream out(&logFile); out << QString("D1: %1\n D2: %2\n E2: %3\n E3: %4\n E4: %5\n Z: %6\n") .arg(D1).arg(D2).arg(E2).arg(E3).arg(E4).arg(Z_EDGE); logFile.close(); std::cout << logFileName.toStdString().c_str() << std::endl; } else { std::cerr << "Failed to create log file: " << logFileName.toStdString() << std::endl; }
这样写不仅更简洁,还能自动处理编码和跨平台路径的问题,减少踩坑的概率。
内容的提问来源于stack exchange,提问作者Schütze
相关产品推荐
相关产品推荐

