使用std::getline读取FORTRAN文件时如何截断!分隔符后的注释内容
C++ 逐行去除Fortran注释实现方案
针对用std::getline读取Fortran格式参数文件、去除!开头注释的需求,核心逻辑是对每行字符串定位第一个注释分隔符位置,截断后续内容即可,具体实现和注意事项如下:
- 基础场景(确认参数值中不会出现
!字符):直接调用字符串的find方法查找第一个!的位置,截取子串即可,覆盖三种常规情况:行首为!(整行注释,有效内容为空)、行中存在!(保留分隔符前内容)、行内无!(整行保留) - 进阶场景(参数值可能包含被引号包裹的
!,比如字符串类型参数、带!的路径):需要逐字符扫描,识别当前是否处于单/双引号包裹的字符串内部,仅将字符串外的!判定为注释起始符 - 可选优化:截断注释后建议剔除行尾多余的空格、制表符、回车符,避免无意义空白干扰后续参数解析逻辑
基础版本实现代码
#include <fstream> #include <string> int main() { std::ifstream param_file("your_input_file.inc"); std::string raw_line; while (std::getline(param_file, raw_line)) { std::string valid_content = raw_line; // 定位第一个注释分隔符 size_t comment_start = valid_content.find('!'); if (comment_start != std::string::npos) { valid_content = valid_content.substr(0, comment_start); } // 剔除行尾无效空白 size_t valid_end = valid_content.find_last_not_of(" \t\r"); if (valid_end != std::string::npos) { valid_content = valid_content.substr(0, valid_end + 1); } else { valid_content.clear(); } // valid_content即为去除注释后的有效内容,可直接传入后续参数解析逻辑 } return 0; }
兼容字符串内!的进阶实现
如果文件中存在引号包裹的字符串参数(例如file_path = 'data!test.txt'),基础版本会误截断字符串内的!,可使用逐字符扫描的方式处理:
std::string strip_fortran_comment(const std::string& raw_line) { std::string valid_part; bool in_single_q = false; bool in_double_q = false; for (char ch : raw_line) { // 切换单引号包裹状态 if (ch == '\'' && !in_double_q) { in_single_q = !in_single_q; valid_part.push_back(ch); continue; } // 切换双引号包裹状态 if (ch == '"' && !in_single_q) { in_double_q = !in_double_q; valid_part.push_back(ch); continue; } // 遇到字符串外的!,直接终止拼接 if (ch == '!' && !in_single_q && !in_double_q) { break; } valid_part.push_back(ch); } // 可按需追加行尾空白剔除逻辑 return valid_part; }
注意:如果读取的是老式固定格式Fortran文件(第1列为
C/c代表整行注释、第6列后为注释区的写法),还需要额外增加列位置判断逻辑,自由格式Fortran文件仅需按上述!分隔规则处理即可。
内容的提问来源于stack exchange,提问作者YS_Jin
相关产品推荐
相关产品推荐

