C++中如何判断system()函数执行结束,正确读取其生成的临时文件
解决方案
核心认知纠正
C/C++标准中的
system()函数本身是同步阻塞调用,仅当你传入的命令中主动加入后台运行标识(如Linux下的&后缀)时才会提前返回。你当前的调用写法下,system会等待figlet命令执行完成、临时文件写入关闭后才会返回,完全不需要额外加sleep轮询判断文件状态。
现有代码问题梳理
- 命令拼接错误:
figlet -f和用户输入的字体名之间缺少空格,会直接导致命令执行失败 - 逻辑错误:do-while循环内无论文件是否打开成功都会输出错误提示,且打开失败的文件流没有关闭,后续重试会持续失败
- 安全风险:直接拼接用户输入到系统命令,存在命令注入漏洞
- 冗余逻辑:system返回后临时文件已经就绪,完全不需要轮询等待
方案1:修正现有临时文件实现
#include <iostream> #include <string> #include <fstream> #include <cstdlib> #include <cstdio> // 用于删除临时文件 int main() { std::string font_name, cmd; std::cin >> font_name; // 建议先校验font_name仅包含合法字符,避免命令注入风险 cmd = "figlet -f " + font_name + " > tmp.txt"; int cmd_ret = system(cmd.c_str()); if (cmd_ret != 0) { std::cerr << "figlet命令执行失败,请检查字体是否存在" << std::endl; return 1; } std::ifstream tmp_file("tmp.txt"); if (!tmp_file.is_open()) { std::cerr << "临时文件打开失败" << std::endl; return 1; } std::string line; while (std::getline(tmp_file, line)) { std::cout << line << std::endl; } tmp_file.close(); std::remove("tmp.txt"); // 清理临时文件 return 0; }
方案2:更推荐的无临时文件实现
使用popen直接读取figlet的标准输出,无需磁盘文件中转,逻辑更简洁可靠:
#include <iostream> #include <string> #include <cstdio> int main() { std::string font_name, cmd; std::cin >> font_name; // 建议先校验font_name仅包含合法字符,避免命令注入风险 cmd = "figlet -f " + font_name; FILE* pipe = popen(cmd.c_str(), "r"); if (!pipe) { std::cerr << "创建进程管道失败" << std::endl; return 1; } char buffer[1024]; while (fgets(buffer, sizeof(buffer), pipe) != nullptr) { std::cout << buffer; } pclose(pipe); // 自动等待子进程执行完成 return 0; }
内容的提问来源于stack exchange,提问作者Laxe96
相关产品推荐
相关产品推荐

