1

私は C++ を使って約 6 か月しか経っていないので、コードで愚かな間違いを犯したことをお詫びします。

バイナリ ファイルを streambuf に読み込み、streambuf で特定のシーケンスを検索し、バイナリ ファイルのシーケンス開始オフセットと、バイナリ ファイルで特定のシーケンスが見つかった識別子を報告するプロジェクトに取り組んでいます。

検索するシーケンスは、snortRules ベクトルの各インデックスが int のベクトルとして格納される単一のシーケンスである snortRules と呼ばれる vector> に格納されます。

最終的には、一致するはずの別のファイルと比較するために見つかったオフセットと特定のシーケンスを表示するテキスト ファイルを作成する必要がありますが、今のところ、結果をコンソール ウィンドウに出力するだけです。

私のコードは、1 つの問題を除くすべてのシーケンスを見つけたと報告しているため、機能しているようです。何らかの理由で、シーケンスが見つかった場所のオフセットが繰り返されることがあります。たとえば、出力は次のようになります。

101521 #655
101816 #656    <--This output is correct
101816 #657    <--This output is wrong and should have offset 101865 
101893 #658    <--This output is correct
101893 #659    <--This output is wrong and should have offset 102084
102105 #660
102325 #661
102378 #662

私の問題は、streambuf の pubseekoff を使用してオフセットを正しく取得していないことだと思います。

私のコードは次のとおりです。

fstream binFS(binName, ios::in | ios::binary); //create stream 
streambuf* binBuff = binFS.rdbuf(); //create streambuf from filestream
int currentChar; //ascii code of current character from binary file
streamsize offset; //location of first character of rule in binary file
do
{ //until the end of binary file
    for(unsigned i=0; i<snortRules.size(); ++i)
    {//start by finding the begining of current rule    
        do
        { //check binBuff until first char of first rule is found.
            currentChar = binBuff->sgetc();
            if( snortRules[i][0] == currentChar )//binBuff->sgetc() ) //compare short rule 1st char to curtent position 
            { //match save offset and compare rest of rule
                offset = binBuff->pubseekoff(0,ios::cur); //set the offset to current postion
                bool checkNext = true; //bool to break loop when checking rules if not matching
                for(unsigned srIdx=0; srIdx < snortRules[i].size() && checkNext == true; ++srIdx)
                { //loop through current rule comparing characters                        
                    if(snortRules[i][srIdx] == currentChar)
                    { //match check if end of rule or advance character to compare to next in rule
                        if( srIdx == snortRules[i].size()-1)
                        { //match write the offset of fist character of rule and which was matched
                            std::cout<<offset<<" #"<<i+1<<endl; //write to console for debugging purposes will write to text file when working
                            ++i; //increment rule to next when exact match found
                        }
                        else
                        { //not at the end of the rule so continue to compare next characters
                            currentChar = binBuff->snextc(); //set currentChar to next char to be checked by for loop
                        }
                    }
                    else
                    { //no match break out and continue 
                        checkNext == false; //set flag to break for loop because characters didnt match
                    }
                }
            }
            else
            { //no match check next character in binBuff
                //offset = binBuff->pubseekoff (0,binFS.cur, binFS.in); //set the offset to current postion
                currentChar = binBuff->snextc(); //get next char in binBuff
                //offset = binBuff->pubseekoff (0,binFS.cur, binFS.in); //set the offset to current postion
            }
        }while( currentChar != streambuf::traits_type::eof() ); //stop checking if end of file reached
    }
}while( binBuff->snextc() != streambuf::traits_type::eof() ); //stop checking if end of file reached

stackoverflow.com と cplusplus.com で pubseekoff のドキュメントと例を見つけようとしましたが、見つけたものはあまり意味がなく、正直なところ、それが私の問題であると 100% 確信していません...

どんな助けや提案も大歓迎です!

4

1 に答える 1

1

全体の問題は次の行でした。

checkNext == false;

次のようにする必要があるため、「==」は効果がなく、エラーが発生します。

checkNext = false;

ブール値を割り当て、適切なタイミングでループを終了するようにします。

Visual Studio のコンパイラが発行する警告を見逃して、数時間尻尾を追いかけました。

したがって、streambuf の複雑な例が必要な場合は、これが役立つ場合があります。また、意味をなさないランダムな実行時エラーが発生している場合は、警告を確認してください。

于 2013-04-27T14:08:39.833 に答える