I'm trying to make a program that deletes duplicates of files with the same name (ignoring extension) but I have some problems. Here is all code, the problems are at the end (atleast I think so :P).
#include <windows.h>
#include <string>
#include <vector>
#include <fstream>
#include <algorithm>
using namespace std;
typedef vector< WIN32_FIND_DATA > FileList;
void Split( vector< string >& out,
const string& str,
const string& delim )
{
string::size_type firstPos = 0;
string::size_type secondPos = str.find_first_of( delim );
out.push_back( str.substr( firstPos, secondPos ) );
while( secondPos != string::npos )
{
firstPos = secondPos + 1;
secondPos = str.find_first_of( delim, firstPos );
out.push_back( str.substr( firstPos, secondPos - firstPos ) );
}
}
bool IsDirectory( const WIN32_FIND_DATA& data )
{
return data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
}
bool NoExtCmp( const WIN32_FIND_DATA& data1, const WIN32_FIND_DATA& data2 )
{
string s1 = data1.cFileName, s2 = data2.cFileName;
s1 = s1.substr( 0, s1.size() - s1.find_last_of( "." ) );
s2 = s2.substr( 0, s2.size() - s2.find_last_of( "." ) );
return s1 == s2;
}
int WINAPI WinMain( HINSTANCE instance, HINSTANCE prevInstance,
char* cmdLine, int cmdShow )
{
FileList files;
ofstream file( "log.txt" );
vector< string > cmd;
Split( cmd, cmdLine, " " );
string dir;
try
{
dir = cmd.at( 0 );
}
catch( out_of_range& e )
{
file << "first commandline argument should be the path to search" << endl;
return -1;
}
file << "Target directory: " << dir << '\n' << endl;
dir += "\\*";
WIN32_FIND_DATA FindFileData;
HANDLE hFind = FindFirstFile( dir.c_str(), &FindFileData );
if( hFind == INVALID_HANDLE_VALUE )
{
file << "Invalid file handle. Error is " << GetLastError() << endl;
return -1;
}
else
{
if( !IsDirectory( FindFileData ) )
{
files.push_back( FindFileData );
}
while( FindNextFile( hFind, &FindFileData ) )
{
if( !IsDirectory( FindFileData ) )
{
files.push_back( FindFileData );
}
}
DWORD dwError = GetLastError();
if( dwError == ERROR_NO_MORE_FILES )
{
FindClose( hFind );
}
else
{
file << "FindNextFile error. Error is " << dwError << endl;
return -1;
}
}
file << "Before:" << endl;
for( FileList::iterator it( files.begin() ), end( files.end() );
it != end; ++it )
{
file << it->cFileName << '\n';
}
file << endl;
FileList::iterator pos = unique( files.begin(), files.end(), NoExtCmp );
for( FileList::iterator it( pos ), end( files.end() ); it != end; ++it )
{
if( DeleteFile( it->cFileName ) )
{
file << it->cFileName << " deleted\n";
}
else
{
file << "could not delete " << it->cFileName << '\n';
}
}
file << endl;
files.erase( pos, files.end() );
file << "After:" << endl;
for( FileList::iterator it( files.begin() ), end( files.end() );
it != end; ++it )
{
file << it->cFileName << '\n';
}
return 0;
}
After I run this log.txt looks like this:
Target directory: c:\test
Before:
hehe.tr1
hehe.tr2
okej.tr1
test.tr1
test.tr2
test.tr3
test.tr4
test.tr5
test.tr6
could not delete test.tr1
could not delete test.tr2
could not delete test.tr3
could not delete test.tr4
could not delete test.tr5
could not delete test.tr6
After:
hehe.tr1
okej.tr1
test.tr1
The first question I have is, why couldn't the files be deleted? The second, the files that should be deleted are test.tr2-6 and hehe.tr2, but the program tries to delete all files named test. When I erase the duplicates from the vector the right files are left in it. I don't understand why that is happening. Probably some stupid mistake after the call to uniqe.