我试图消除文本文件中的注释,空行和额外空格,然后将剩余的元素标记化。每个令牌前后都需要一个空格。
exampleFile.txt
var
/* declare variables */a1 ,
b2a , c,
这是现在的工作,
string line; //line: represents one line of text from file
ifstream InputFile("exampleFile", ios::in); //read from exampleFile.txt
//Remove comments
while (InputFile && getline(InputFile, line, '\0'))
{
while (line.find("/*") != string::npos)
{
size_t Begin = line.find("/*");
line.erase(Begin, (line.find("*/", Begin) - Begin) + 2);
// Start at Begin, erase from Begin to where */ is found
}
}
这会删除评论,但在发生这种情况时,我似乎无法想出一种标记化的方法。
所以我的问题是:
先谢谢你的帮助!
答案 0 :(得分:0)
如果您需要跳过空白字符并且不关心新行,那么我建议您使用operator>>
来阅读该文件。
你可以简单地写一下:
std::string word;
bool isComment = false;
while(file >> word)
{
if (isInsideComment(word, isComment))
continue;
// do processing of the tokens here
std::cout << word << std::endl;
}
辅助函数的实现方式如下:
bool isInsideComment(std::string &word, bool &isComment)
{
const std::string tagStart = "/*";
const std::string tagStop = "*/";
// match start marker
if (std::equal(tagStart.rbegin(), tagStart.rend(), word.rbegin())) // ends with tagStart
{
isComment = true;
if (word == tagStart)
return true;
word = word.substr(0, word.find(tagStart));
return false;
}
// match end marker
if (isComment)
{
if (std::equal(tagStop.begin(), tagStop.end(), word.begin())) // starts with tagStop
{
isComment = false;
word = word.substr(tagStop.size());
return false;
}
return true;
}
return false;
}
对于你的例子,这将打印出来:
var
a1
,
b2a
,
c,
如果您感兴趣,上述逻辑还应处理多行评论。
但是,表示应根据您对注释令牌的假设修改函数实现。例如,它们是否总是与其他words
的空格分开?或者是否可能会解析var1/*comment*/var2
表达式?上面的例子在这种情况下不会起作用。
因此,另一种选择是(您已经开始实施的)从文件中读取行甚至数据块(以确保匹配开始和结束注释标记)以及使用find或{{3来学习注释标记的位置之后删除它们。