2009-06-30 87 views
0

我很難在C++中使用std :: string :: iterators。這段代碼在Dev-C++中編譯得很好(仍然沒有得到正確的輸出,但那是我的錯:TODO,修復算法),並且我沒有得到運行時錯誤。錯誤是在Visual Studio Express 2008 C++中,我得到一個指向< xstring>:「Expression:string iterator not derefereenable」的錯誤,並指向< xstring>文件的第112行。表達式:字符串迭代器不可忽略

我的調試告訴我,我可能試圖解引用過去的句子輸入結束,但我看不到在哪裏。任何人都可以點亮一下嗎?

std::string wordWrap(std::string sentence, int width) 
{  
    std::string::iterator it = sentence.begin(); 

    //remember how long next word is 
    int nextWordLength = 0; 
    int distanceFromWidth = width; 

    while (it < sentence.end()) 
    { 
     while (*it != ' ' && it != sentence.end()) 
     { 
      nextWordLength++; 
      distanceFromWidth--; 
      it++; 
     } 

     if (nextWordLength > distanceFromWidth) 
     { 
      *it = '\n'; 
      distanceFromWidth = width; 
      nextWordLength = 0; 
     } 

     //skip the space 
     it++; 

    } 

    return sentence;  
} 

回答

15

首先,使用操作符=()的迭代器,而不是運營商<():

while (it != sentence.end()) 

其次,這是倒退:while (*it != ' ' && it != sentence.end())

你用迭代器做了一些事情,而不是檢查迭代器是否有效。相反,你應該檢查是否是有效的第一:

while (it != sentence.end() && *it != ' ') 

第三,你應該使用了迭代器++ ++迭代器,雖然這是不相關的崩潰。


第四,一個主要的問題是在這裏:

*it = '\n'; 

由於前述檢查,while (it != sentence.end()的,有可能達到這個迭代器提領,同時在最後。解決辦法是做到這一點:

if (it != sentence.end() && nextWordLength > distanceFromWidth) 

所以現在如果你已經到了最後,你停下來。


固定之前的問題後,現在唯一的問題是這樣的:

//skip the space 
++it; 

這假定您跳過的字符實際上是一個空間。但是,字符串的結尾呢?與此字符串運行這個功能:

"a test string " // <- space at end

它會成功;它跳過空間,將迭代器置於end(),循環退出併成功。

但是,沒有空間它會崩潰,因爲你已經到了最後,並且正在跳過最後。要修復,添加一個檢查:

//skip the space 
if (it != sentence.end()) 
{ 
    ++it; 
} 

在這最後的代碼得到的:

std::string wordWrap(std::string sentence, int width) 
{  
    std::string::iterator it = sentence.begin(); 

    //remember how long next word is 
    int nextWordLength = 0; 
    int distanceFromWidth = width; 

    while (it != sentence.end()) 
    { 
     while (it != sentence.end() && *it != ' ') 
     { 
      nextWordLength++; 
      distanceFromWidth--; 
      ++it; 
     } 

     if (it != sentence.end() && nextWordLength > distanceFromWidth) 
     { 
      *it = '\n'; 
      distanceFromWidth = width; 
      nextWordLength = 0; 
     } 

     //skip the space 
     if (it != sentence.end()) 
     { 
      ++it; 
     } 

    } 

    return sentence;  
} 

您可能會注意到這似乎是它有很多冗餘檢查。這可以是固定的:

std::string wordWrap(std::string sentence, int width) 
{  
    std::string::iterator it = sentence.begin(); 

    //remember how long next word is 
    int nextWordLength = 0; 
    int distanceFromWidth = width; 

    while (it != sentence.end()) 
    { 
     while (*it != ' ') 
     { 
      nextWordLength++; 
      distanceFromWidth--; 

      ++it; 

      // check if done 
      if (it == sentence.end()) 
      { 
       return sentence; 
      } 
     } 

     if (nextWordLength > distanceFromWidth) 
     { 
      *it = '\n'; 
      distanceFromWidth = width; 
      nextWordLength = 0; 
     } 

     //skip the space 
     ++it; 
    } 

    return sentence;  
} 

希望幫助!

+0

+1。我已經糾正了第2點中的代碼,以使其與代碼的完整代碼塊和解釋一致。 – 2009-06-30 07:22:09

5
while (*it != ' ' && it != sentence.end()) 

更改

while (it != sentence.end() && *it != ' ') 

所以第二個表達式不評估如果第一如果爲假。

if (nextWordLength > distanceFromWidth) 

或許應該改爲

if (it == sentence.end()) 
     break; 
    if (nextWordLength > distanceFromWidth) 
0

幾乎可以肯定你的錯誤的結果是:

*it = '\n'; 

由於同時你停止狀況一環就是前面:

it != sentence.end() 

如果== sentence.end()那麼* it ='\ n'不會飛

還有更多的錯誤,但這是造成您目前的問題。