到目前为止,我一直在遵循这个惯例:
std::string line;
while(std::getline(in,line))
{
if(line.size() && line[0] =='#')
continue;
/* parse text*/
}
明显的缺点是,在引导空格的情况下,注释可能不会从第一个字符开始。
处理这类事情的好方法是什么?
答案 0 :(得分:11)
简单增强:您可能希望使用line.find_first_not_of(“”)来获取第一个非空格,然后检查 是否为'#'。这也将涵盖零长度的情况。类似这样的片段:
found= line.find_first_not_of(" \t");
if( found != string::npos)
{
if( line[found] == '#')
continue;
}
答案 1 :(得分:3)
使用运算符>>。它忽略了空白。
std::string line;
while(std::getline(in,line))
{
std::stringstream linestr(line);
char firstNoWhiteSpaceChar;
linestr >> firstNoWhiteSpaceChar;
if ((!linestr) || (firstNoWhiteSpaceChar == '#'))
{
// If line contains only white space then linestr will become invalid.
// As the equivalent of EOF is set. This is the same as a comment so
// we can ignore the line like a comment.
continue;
}
// Do Stuff with line.
}
答案 2 :(得分:2)
在测试字符零之前,您应该确保检查字符串长度:
if (line.length() > 0 && line[0] == '#')
答案 3 :(得分:1)
根据事物的声音,您的文件格式指定从“#”到行尾的所有内容都是注释。如果是这种情况,您可以通过以下方式找到评论的开头:
// Warning: untested code.
int pos = line.find('#');
然后,你可能想要忽略该行的其余部分,最容易通过删除它来管理:
if (pos != std::string::npos)
line.erase(pos, -1);
这应该很容易处理:
tax = rate * price # figure tax on item
当然,这假设'#'总是表示评论的开头 - 如果您在字符串中允许'#',或者出于其他目的,您需要考虑到这一点(但很难猜出,因为你告诉我们的文件格式很少)。
答案 4 :(得分:1)
使用流的工具跳过空格std::ws
:
inline std::istream& get_line(std::istream& in, std::string& line)
{
in >> std::ws;
std::getline(in,line);
return in;
}
std::string line;
while(get_line(in,line))
{
if(!line.empty() && line[0] =='#')
continue;
/* parse text*/
}
答案 5 :(得分:0)
您可能会喜欢Boost String Library,特别是trim_left
和starts_with
。
答案 6 :(得分:0)
解析是棘手而困难的。
一般情况下,我不建议在没有状态机的情况下尝试解析。例如,如果'#'是多行的一部分(python中的“”“”“”,该怎么办?
存在可以简化解析的库(好吧,他们应该这样做,但是如果你没有事先知道,理解它们可能会很有挑战性),例如,在C ++中,人们只能推荐Spirit。
已经有一些建议可以帮助您使用字符串方法,但它们只与检测第一个有意义的字符是否为'#'有关。
如果你不“害怕”多线(即如果你要解析的东西没有这样的功能),你仍然需要管理“简单”线,这可以通过计数,逃脱进入帐户:
print "My \"#\" is: ", phoneNumber # This is my phone number
如果你严重解析这一行,你最终会得到一个错误......(例如)
如果您不能使用库,那么状态机是可行的方法,编写解析器通常非常有趣,它可以让您深入了解为何以某种方式开发符号。