 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Siemel Naran Guest
|
Posted: Sun Dec 19, 2004 10:13 am Post subject: compare 2 files |
|
|
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 << "" failedn";
return false;
}
Any comments?
|
|
| Back to top |
|
 |
Ivan Vecerina Guest
|
Posted: Sun Dec 19, 2004 10:29 am Post subject: Re: compare 2 files |
|
|
"Siemel Naran" <SiemelNaran (AT) REMOVE (DOT) att.net> wrote
| Quote: | How to compare if two files are identical? I wrote the following:
....
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();
Since only the stream buffer interface is used, you can directly |
create instances of std::filebuf instead of an ifstream.
| Quote: | char lhschar, rhschar;
These two variables should be of type int_type. char may be unable |
to represent eof (or be equal to eof when it should not, e.g.
when reading 0xFF on an implementation where char is signed).
| Quote: | 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;
}
or: |
do {
lhschar = lhsbuf.sbumpc();
rhschar = rhsbuf.sbumpc();
if( lhschar != rhschar ) return false;
} while( lhschar != eof );
return true;
Cheers,
Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
|
|
| Back to top |
|
 |
Howard Guest
|
Posted: Mon Dec 20, 2004 4:31 pm Post subject: Re: compare 2 files |
|
|
I think the first thing I'd do it check if the file sizes are the same. No
need to read tthrough the file looking for differences if they're different
sizes. I'm not familiar with how to check file size, but if that's easy
enough to do, you might want to throw in a check for that equality before
bothering to check the contents. Just a thought...
-Howard
|
|
| Back to top |
|
 |
Siemel Naran Guest
|
Posted: Mon Dec 20, 2004 6:48 pm Post subject: Re: compare 2 files |
|
|
"Howard" <alicebt (AT) hotmail (DOT) com> wrote
| Quote: | I think the first thing I'd do it check if the file sizes are the same.
No
need to read tthrough the file looking for differences if they're
different
sizes. I'm not familiar with how to check file size, but if that's easy
enough to do, you might want to throw in a check for that equality before
bothering to check the contents. Just a thought...
|
This is the ideal solution, then I can continue to use std::equal as in my
original code. However, the standard does not provide a way to find the
file size without opening it and scanning to the last character. Opening
the file, calling file.seekg(ios::end) followed by file.tellp() is allowed
to return 0 rather than the actual byte position though my implementation
does in fact return the file size. There is a function stat, and it's on
Windows and Linux, but it's not ANSI standard (though maybe it should be).
I know that boost also has some way to get the file size, and I imagine the
implementation calls stat on Windows and Linux, etc.
|
|
| Back to top |
|
 |
Jeff Flinn Guest
|
Posted: Mon Dec 20, 2004 7:11 pm Post subject: Re: compare 2 files |
|
|
Siemel Naran wrote:
| Quote: | "Howard" <alicebt (AT) hotmail (DOT) com> wrote
I think the first thing I'd do it check if the file sizes are the
same. No need to read tthrough the file looking for differences if
they're different sizes. I'm not familiar with how to check file
size, but if that's easy enough to do, you might want to throw in a
check for that equality before bothering to check the contents.
Just a thought...
This is the ideal solution, then I can continue to use std::equal as
in my original code. However, the standard does not provide a way to
find the file size without opening it and scanning to the last
character. Opening the file, calling file.seekg(ios::end) followed
by file.tellp() is allowed to return 0 rather than the actual byte
position though my implementation does in fact return the file size.
There is a function stat, and it's on Windows and Linux, but it's not
ANSI standard (though maybe it should be). I know that boost also has
some way to get the file size, and
|
Yes, at:
http://www.boost.org/libs/filesystem/doc/operations.htm#file_size
| Quote: | I imagine the implementation calls stat on Windows and Linux, etc.
|
Windows: GetFileAttributes()
POSIX: stat()
Jeff Flinn
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|