C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

compare 2 files

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++)
View previous topic :: View next topic  
Author Message
Siemel Naran
Guest





PostPosted: Sun Dec 19, 2004 10:13 am    Post subject: compare 2 files Reply with quote



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





PostPosted: Sun Dec 19, 2004 10:29 am    Post subject: Re: compare 2 files Reply with quote



"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





PostPosted: Mon Dec 20, 2004 4:31 pm    Post subject: Re: compare 2 files Reply with 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...

-Howard


Back to top
Siemel Naran
Guest





PostPosted: Mon Dec 20, 2004 6:48 pm    Post subject: Re: compare 2 files Reply with quote

"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





PostPosted: Mon Dec 20, 2004 7:11 pm    Post subject: Re: compare 2 files Reply with quote

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
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language (comp.lang.c++) All times are GMT
Page 1 of 1

 
Jump to:  
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


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.