2016-09-11 201 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函數有問題。我會更新我的問題以顯示代碼。 –