2016-10-07 19 views
0

ライブラリを使用して.pgnファイルを解析していますが、プロジェクトを実行しようとしたときにこのエラーが見つかりました:デバッグアサーションに失敗しました!プログラム:C:\ windows \ SYSTEM32 \ MSVCP110D.dllファイル:c:\ program files(x86)\ microsoftビジュアルスタジオ11.0 \ vc \ include \ xstring 行:79 式:文字列イテレータは逆参照できません プログラムがアサーションの失敗を引き起こす可能性があります。アサーションに関するVisual C++のドキュメントを参照してください。文字列イテレータは逆参照できません

問題は、イテレータがファイルの最後に到達したときに何も指していない(イテレータ(itr1)==終了イテレータ(itr2)を開始します)、itr1が到達したかどうかをチェックする条件を追加しようとしました。ファイルの末尾が無駄でした。 だから私の誤りはどこにあるのか教えてください。 は、ここに私のコードsource.cppファイルです:

#include <iostream> 
#include <fstream> 
#include <PGNGameCollection.h> 
int main() 
{ 
    std::ifstream pgnfile("sample.pgn"); 
    pgn::GameCollection games; 
    pgnfile >> games; 
    std::cout << "the file sample.pgn contains " << games.size() << "games"  << std::endl; 
    system("pause"); 
    return 0; 
} 

とここでエラー原因クラスの関数である:

bool pgn::Parser::getComment(std::string::const_iterator &itr1, const std::string::const_iterator &itr2, pgn::CommentText &out) 
{ 
    std::string::const_iterator local_itr=itr1; 
    std::string comment; 
    if(*local_itr != '{') 
     return false; 
    local_itr++; //skipping '{' 

    while((*local_itr != '}') && (local_itr != itr2)) 
    { 
     comment += *local_itr++; 
    } 
    local_itr++; //skipping '}' 
    skipBlanks(local_itr, itr2); 
    itr1=local_itr; 
    out=pgn::CommentText(comment); 
    return true; 
} 

skipBlanks機能:

void pgn::Parser::skipBlanks(std::string::const_iterator &itr1, cost std::string::const_iterator &end) 
{ 
    while((itr1 != end) && (isspace(*itr1))) 
    { 
     itr1++; 
    } 
} 

私が検索しましたstackoverflowのとをGoogleはすべての同様の問題のために私は答えを見つけることができませんでした。また、エラーの原因となった関数に到達するまで、コードを行単位でトレースしました。

+0

このような問題を解決する適切なツールは、デバッガです。スタックオーバーフローを尋ねる前に、コードを一行ずつ進める必要があります。詳しいヘルプは、[小さなプログラムをデバッグする方法(Eric Lippert)](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/)を参照してください。最低限、問題を再現する[最小、完全、および検証可能](http://stackoverflow.com/help/mcve)の例と、その問題を再現するためのデバッガ。 –

+0

私は既にここで質問する前にコードを1行ずつデバッグしましたが、答えが見つかりませんでした! –

+0

次に、デバッガを間違った方法で使用している可能性があります。デバッガを使用して –

答えて

1

itr2があなたのエンドイテレータであれば、あなたはそれを間接参照

while((local_itr != itr2) && (*local_itr != '}')) 

しようとして前に終了条件のためにあなたのイテレータを確認する必要がありますあなたは間違いなくつながるれ、それを他の方法で回避を行っていますあなたが説明した問題に。

関数の冒頭に終了条件のチェックを追加することも意味があります。そこには逆参照local_itrもあるためです。

また、local_itritr2に達したためにサイクルが終了し、itr2に何もない場合、サイクルの後のコードは意味をなさない。その状況でlocal_itrを増やすことはできません。

+0

これを試しましたが、同じエラーメッセージが式で表示されました:文字列イテレータがインクリメンタルでない –

+0

@ノルマンフォダ:ええと...同じですか?どのように同じですか?あなたは元のエラーを "文字列反復子is not ** ** dereferencable **"と引用しました。 「インクリメンタルではない」というのは、サイクルの後に 'local_itr ++'を実行しようとしたときのエラーとはまったく異なっています。後者は、あなたが終わりに達しても意味をなさない。これは別の問題であり、別の修正が必要です。イテレーターをインクリメントしようとしないでください。イテレーターがすでに終了している場合は、イテレーターを読み込まないでください。 – AnT

+0

イテレータが次のように最後に達したかどうかを確認しました:if(itr1!= itr2){local_itr ++;} local_itrはファイルの最後でない場合にだけインクリメントされます。これは逆参照できない文字列イテレータに戻ります。 –

関連する問題