13

単体テストを書いているので、結果ファイルをゴールデンファイルと比較する必要があります。そうするための最も簡単な方法は何ですか?

これまでのところ(Linux環境の場合):

int result = system("diff file1 file2");

それらは異なる場合result != 0

4

5 に答える 5

24

純粋なC++ソリューションが必要な場合は、次のようにします

#include <algorithm>
#include <iterator>
#include <string>
#include <fstream>

template<typename InputIterator1, typename InputIterator2>
bool
range_equal(InputIterator1 first1, InputIterator1 last1,
        InputIterator2 first2, InputIterator2 last2)
{
    while(first1 != last1 && first2 != last2)
    {
        if(*first1 != *first2) return false;
        ++first1;
        ++first2;
    }
    return (first1 == last1) && (first2 == last2);
}

bool compare_files(const std::string& filename1, const std::string& filename2)
{
    std::ifstream file1(filename1);
    std::ifstream file2(filename2);

    std::istreambuf_iterator<char> begin1(file1);
    std::istreambuf_iterator<char> begin2(file2);

    std::istreambuf_iterator<char> end;

    return range_equal(begin1, end, begin2, end);
}

ファイル全体をメモリに読み込むことを回避し、ファイルが異なるとすぐに(またはファイルの終わりで)停止します。range_equalstd::equalは、2番目の範囲にイテレーターのペアを使用しないため、2番目の範囲が短い場合は安全ではありません。

于 2013-02-27T18:18:46.833 に答える
7

DaveS's answerから開発し、最初にファイル サイズをチェックします

#include <fstream>
#include <algorithm>

bool compare_files(const std::string& filename1, const std::string& filename2)
{
    std::ifstream file1(filename1, std::ifstream::ate | std::ifstream::binary); //open file at the end
    std::ifstream file2(filename2, std::ifstream::ate | std::ifstream::binary); //open file at the end
    const std::ifstream::pos_type fileSize = file1.tellg();

    if (fileSize != file2.tellg()) {
        return false; //different file size
    }

    file1.seekg(0); //rewind
    file2.seekg(0); //rewind

    std::istreambuf_iterator<char> begin1(file1);
    std::istreambuf_iterator<char> begin2(file2);

    return std::equal(begin1,std::istreambuf_iterator<char>(),begin2); //Second argument is end-of-range iterator
}

(巻き戻しの前に、ストリームの長さを知ることで、一度により多くのバイトを処理fileSizeできる、より効率的なストリーム終了イテレータを作成するために使用できるのではないかと思います)。std::equal

于 2016-08-23T09:17:33.057 に答える
2

両方のファイルを読み取らないようにする 1 つの方法は、ゴールデン ファイルを事前に計算してハッシュ (md5 など) にすることです。あとはテストファイルをチェックするだけです。これは、両方のファイルを読み取るよりも遅くなる可能性があることに注意してください!

または、チェックを重ねてください。ファイルサイズが異なる場合は、ファイルが異なるため、時間のかかる読み取りと比較操作を回避できます。

于 2013-02-27T17:50:21.747 に答える
0

やり過ぎかもしれませんが、boost/bimapとboost/scope_exitを使用してハッシュSHA-256のテーブルを作成できます。

これは、Stephan T Lavavejによるこれを行う方法のビデオです(8.15から開始): http ://channel9.msdn.com/Series/C9-Lectures-Stephan-T-Lavavej-Advanced-STL/C9-Lectures-Stephan- T-Lavavej-Advanced-STL-5-of-n

アルゴリズムの詳細については、http: //en.wikipedia.org/wiki/SHA-2をご覧ください。

于 2013-02-27T18:19:03.733 に答える
0

これはうまくいくはずです:

#include <string>
#include <fstream>
#include <streambuf>
#include <iterator>


bool equal_files(const std::string& a, const std::string& b)
  std::ifstream stream{a};
  std::string file1{std::istreambuf_iterator<char>(stream),
                    std::istreambuf_iterator<char>()};

  stream = std::ifstream{b};
  std::string file2{std::istreambuf_iterator<char>(stream),
                    std::istreambuf_iterator<char>()};

  return file1 == file2;
}

これは ほど速くないと思いますdiffが、 の呼び出しを回避し systemます。ただし、テストケースには十分なはずです。

于 2013-02-27T17:48:15.867 に答える