2016-09-11 193 views
0

我正在做一个从文本文件中读取数据的任务,我必须将数据放入一个向量中,同时过滤掉以0和注释开头的数字。除了评论的过滤之外,我已经把所有东西都放下了我理论上应该有效,但我只是在执行时遇到问题。这就是问题的代码:C++:从字符串中删除注释?

vector<string> nums_after; 
for(int i = 0; i < nums_before.size(); i++) 
{ 
    string current = nums_before[i]; 
    if (current.front() == '(') 
    { 
     current.erase(current.find("(*"), current.find("*)")); 
    } 
    if (current.front() == '0') 
    { 
     continue; 
    } 
    nums_after.push_back(current); 
} 

我的示例文件看起来像这样:

101481 
10974 
1013 
(* comment *)0 
28292 
35040 
35372 
0000 
7155 
7284 
96110 
26175 

但我的代码只在星号后过滤掉(*甚至没有空格我想我(*,comment和*),我的问题是注释行被分解成三个单独的行:(*,comment和*)。 0.我现在怀疑我的getline函数有问题,这是它的外观s像:

int main() { 
string line; 
string fileName; 
cout << "Enter the name of the file to be read: "; 
cin >> fileName; 

ifstream inFile{fileName}; 

istream_iterator<string> infile_begin {inFile}; 
istream_iterator<string> eof{}; 
vector<string> nums_before {infile_begin, eof}; 
while (getline(inFile, line)) 
{ 
    nums_before.push_back(line); 
} 

这就在第一个代码块之前。

+0

你应该如何处理嵌套注释? '10 03(* 05 11(* 10 03 *)10 01 *)03 100'需要不同的解析方法,具体取决于您的指示说什么。编辑:你也只解析整数? – druckermanly

+0

我应该摆脱评论之间的任何内容,但我的程序应该能够处理的文本文件没有嵌套评论 –

+0

请检查我的答案。你需要知道,擦除需要开始位置和AMOUNT字符擦除,而不是结束位置 - 不是'(开始,结束)',而是'(开始,结束 - 开始)' - 这将删除'begin'之间的所有字符和'end',但它不会碰到找到的结尾字符,所以你需要在你的例子中添加它们的数量2。 – xinaiz

回答

0

nums_before是什么?我猜测全文被空格分割了? 在这种情况下它是有道理的,它只删除(*,因为这就是你正在看的当前字符串中的内容是“(*”。下一个字符串是“comment”,下一个是“*) 0"

+0

对不起,nums_before是从文件中提取的原始数据,nums_after在过滤掉前导零数字和注释之后应该只是整数。写入文本的方式我没有在代码中完成,所以包含(* comment *)0的所有整数应该是一行 –

0
在这种情况下

,应该选择一个stack数据结构或反向迭代

void func (int &error, int inc, int &i) { 
    error += inc; 
    i -= 2; 
} 

string output; 
for (int i=nums_before.size()-1; i>=0; ++i) { 
    if (nums_before[i] == ')' && nums_before[i-1] == '*') { 
     static int error; 
     func (error, 1, i); 

     while (error != 0) { 
      if (nums_before[i] == ')' && nums_before[i-1] == '*') 
       func (error, 1, i); 
      else if (nums_before[i] == '*' && nums_before[i-1] == '(') 
       func (error, -1, i); 
      else --i; 
     } 
    } else output += nums_before[i]; 
} 

cout << output.reverse() << endl; 

输入:101481 10974 1013 (* comment *)0 28292 35040 35372 0000 7155 7284 96110 26175

输出:101481 10974 1013 0 28292 35040 35372 0000 7155 7284 96110 26175

0

简单的解决方案但嵌套注释不支持:

std::string removeComments(std::string str) 
{ 
    std::string::size_type begin, end; 
    while((begin = str.find("(*")) != std::string::npos) 
    { 
     if(((end = str.find("*)")) != std::string::npos) && (end > begin)) 
      str.erase(begin, end - begin + 2); 
     else 
      break; 
    } 
    return str; 
} 

测试:

std::string test = "1745 2355 (* comment *) 0 1454 4352 4234 (* comment *)"; 
std::cout << removeComments(test) << std::endl; 

输出:

1745 2355 0 1454 4352 4234 

实施例,而无需使用功能:

std::vector<std::string> strings; 
for(int i=0; i<strings.size(); ++i) 
{ 
    std::string::size_type begin, end; 
    while((begin = strings[i].find("(*")) != std::string::npos) 
    { 
     if(((end = strings[i].find("*)")) != std::string::npos) && (end > begin)) 
      strings[i].erase(begin, end - begin + 2); 
     else 
      break; 
    } 
} 
+0

我试图将您的想法合并到我的代码中,但没有得到相同的输出。我的语法可能是错误的,因为我没有将它用作函数,因为我们应该将它作为没有函数的直接代码来执行。我用代码的第3-10行代替了第7行代码。 –

+0

@AlyssaJune编辑 - 添加不太多的修改版本不使用功能。 – xinaiz

+0

它没有工作,然后我改变了我的打印功能,以分隔数据与新行,而不是空格,并看到(*是一行,评论是另一个,*)0是第三行。现在我怀疑我的getline函数有问题。我会更新我的问题以显示代码。 –