S
Siemel Naran
How to compare if two files are identical? I wrote the following:
bool comparefiles(const std::string& lhs, const std::string& rhs)
{
std::ifstream lhsfile(lhs.c_str());
std::ifstream rhsfile(rhs.c_str());
typedef std::istreambuf_iterator<char> istreambuf_iterator;
return std::equal(
istreambuf_iterator(lhsfile),
istreambuf_iterator(),
istreambuf_iterator(rhsfile)
);
}
But I don't think it will work becuase: (1) we only compare the first N
chars where N is the number of chars in lhsfile, so if rhsfile has more
chars the function will return true if the first N are equal which is
incorrect, (2) the standard says that calling operator* on an end of stream
is undefined (24.5.3.3), so if lhsfile has more chars then we will at some
point call operator* on rhsfile when it is at EOF, and the result is
undefined (though I think it should always return EOF).
So what else can we do?
I could use the stat function to check if lhsfile and rhsfile have the same
size, but I want to keep my code ANSI compatible.
So I came up with the following function, which looks very much like strcmp.
bool comparefiles(const std::string& lhs, const std::string& rhs)
{
using namespace std;
const streambuf::int_type eof = streambuf::traits_type::eof();
ifstream lhsfile(lhs.c_str());
ifstream rhsfile(rhs.c_str());
streambuf * lhsbuf = lhsfile.rdbuf();
streambuf * rhsbuf = rhsfile.rdbuf();
char lhschar, rhschar;
while (true)
{
lhschar = lhsbuf->sbumpc();
rhschar = rhsbuf->sbumpc();
if (lhschar == eof && rhschar == eof) return true;
if (lhschar == eof || rhschar == eof) break;
if (lhschar != rhschar) break;
}
cout << "compare \"" << lhs << "\" and \"" << rhs << "\" failed\n";
return false;
}
Any comments?
bool comparefiles(const std::string& lhs, const std::string& rhs)
{
std::ifstream lhsfile(lhs.c_str());
std::ifstream rhsfile(rhs.c_str());
typedef std::istreambuf_iterator<char> istreambuf_iterator;
return std::equal(
istreambuf_iterator(lhsfile),
istreambuf_iterator(),
istreambuf_iterator(rhsfile)
);
}
But I don't think it will work becuase: (1) we only compare the first N
chars where N is the number of chars in lhsfile, so if rhsfile has more
chars the function will return true if the first N are equal which is
incorrect, (2) the standard says that calling operator* on an end of stream
is undefined (24.5.3.3), so if lhsfile has more chars then we will at some
point call operator* on rhsfile when it is at EOF, and the result is
undefined (though I think it should always return EOF).
So what else can we do?
I could use the stat function to check if lhsfile and rhsfile have the same
size, but I want to keep my code ANSI compatible.
So I came up with the following function, which looks very much like strcmp.
bool comparefiles(const std::string& lhs, const std::string& rhs)
{
using namespace std;
const streambuf::int_type eof = streambuf::traits_type::eof();
ifstream lhsfile(lhs.c_str());
ifstream rhsfile(rhs.c_str());
streambuf * lhsbuf = lhsfile.rdbuf();
streambuf * rhsbuf = rhsfile.rdbuf();
char lhschar, rhschar;
while (true)
{
lhschar = lhsbuf->sbumpc();
rhschar = rhsbuf->sbumpc();
if (lhschar == eof && rhschar == eof) return true;
if (lhschar == eof || rhschar == eof) break;
if (lhschar != rhschar) break;
}
cout << "compare \"" << lhs << "\" and \"" << rhs << "\" failed\n";
return false;
}
Any comments?