2014-03-12 79 views
0

我需要編寫一個程序,將程序取出,將其所有///* */註釋全部刪除,最後將其發送到新文件。從字符串中刪除部分字符串到行尾

我遇到的問題是,我無法弄清楚如何在註釋的一行末尾刪除字符串中的字符s.erase。我將整個程序輸入一個字符串,現在我必須找到並刪除註釋。

while (!(filein.eof())) 
{ 
    ch=filein.get(); 
    s.insert(i,1,ch); 
    i++; 
} 
for (i=0;i<s.length();i++) 
{ 
    if((s.at(i) == '/') && (s.at(i+1) == '/')) 
    { 
     s.erase(i, '\n'); 
    } 
} 

我以爲s.erase(i, '\n')將工作,但它只會刪除前10個字符。

+2

第二個要擦除的參數不是一個字符。 – drescherjm

+0

你的程序需要一個cpp文件,而不是二進制/可執行文件,對不對?你是否必須專門使用字符串類及其方法? – user3412759

+0

是的,該程序確實需要一個cpp文件。我也必須使用一個字符串。 – user3412706

回答

2

字符的ASCII碼逃脫字符 '\ n' 爲等於10所以這個調用

s.erase(i, '\n') 

表示從位置i開始移除10個字符。

你需要的東西,如下

#include <iostream> 
#include <string> 

int main() 
{ 
    std::string s("// This is a comment\n a + b/* it is a sum */= c"); 

    std::cout << "\"" << s << "\"" << std::endl; 

    typedef std::string::size_type size_type; 

    if (s.length() > 1) 
    { 
     for (size_type i = 0; i < s.length() - 1; i++) 
     { 
      if (s[i] == '/') 
      { 
       if (s[i+1] == '/') 
       { 
        size_type n = s.find('\n', i + 2); 
        n = n == std::string::npos ? s.length() - i : n - i + 1; 
        s.erase(i, n); 
       } 
       else if (s[i+1] == '*') 
       { 
        size_type n = s.find("*/", i + 2); 
        n = n == std::string::npos ? s.length() - i : n - i + 2; 
        s.replace(i, n, 1, ' '); 
       } 
      } 
     } 
    } 
    std::cout << "\"" << s << "\"" << std::endl; 
} 

輸出是

"// This is a comment 
a + b/* it is a sum */= c" 
" a + b = c" 

要考慮到這個代碼忽略一個反斜槓字符(\)緊接着由刪除的換行符預處理器拼接物理源線以形成邏輯源線。

+0

@DOUGLAS O. MOEN我不明白你在說什麼。 –

+0

@DOUGLAS O. MOEN問題是我的英語不好。:) –

+0

我喜歡你的答案。 –

2

如果你看一下the documentation for erase,你會看到:

basic_string& erase(size_type index = 0, size_type count = npos); 

什麼是你s.erase(i, '\n')情況是,'\n'角色 - 這與ASCII碼10換行符 - 是匹配的count參數,則造成10要刪除的字符。這是因爲char類型是一個整體類型,並受標準轉換爲其他較大的整數類型,如size_type(請參閱標準中的整體促銷 - draft here)。

相反,你應該使用std::string::find找到偏移/指數在評論的開始和終止,並計算字符刪除的數量....

如果你看一下find ...

size_type find(const basic_string& str, size_type pos = 0) const; 

...你會看到有一個pos參數,默認爲0 - 這是開始搜索str的字符串的偏移量。所以,你可以得到一個範圍內構成一個C風格/* ... */評論鏈接這個字符:

while (true) 
{ 
    std::string::size_type from = line.find("/*"); 
    if (from == std::string::npos) 
     break; 
    // a comment begins inside the line 

    std::strings::size_type to = line.find("*/", from); 
    if (to != std::string::npos) 
     line.erase(from, to - from); 
    else 
     line.erase(from); // rest of the line... 
} 

上面沒有溶液滴......你應該想想如何與/*線後,辦理行但沒有匹配*/。這不是特別困難,但是如果我不讓你做某件事,你將不會學習。


另外,而非讀取該文件一次一個字符...

while (!(filein.eof())) 
{ 
    ch=filein.get(); 
    s.insert(i,1,ch); 
    i++; 
} 

...你可以(假設你不處理一個二進制文件,可以合法地包含NUL '\0'字符)簡單地說...

if (std::getline(filein, s, '\0')) 
{ 
    ...it_worked, use s here... 
} 
else 
    std::cerr << "error reading from filein\n"; 
+0

關於閱讀文件,我應該堅持一次閱讀字符,因爲這是我在課堂上學到的。你能解釋更多關於std :: string :: find嗎?對不起,因爲我在介紹性的C++類中。 – user3412706

+0

@ user3412706:好的,我現在編輯一些答案。 –