3

First Problem is solved. Files is perfectly arrange.

for (int i = 0; i < allFiles.GetSize(); i++)
{
    box1.AddString(allFiles[i]);
}

vector<file> files;

vector<tstring> vec;
vec.insert(vec.begin(), &allFiles[0], &allFiles[allFiles.GetSize() - 1] + 1);

transform(vec.begin(), vec.end(),back_inserter(files),[](wstring const &fname)
{
    WIN32_FIND_DATA d;
    HANDLE h = FindFirstFile(fname.c_str(), &d);
    FindClose(h);
    return d;
}

);

sort(files.begin(), files.end());
CStringArray sortFiles;
files.insert(files.begin(), &sortFiles[0], &sortFiles[sortFiles.GetSize() - 1] + 1);

Now The problem is how i save sort files in CStringArray. Last Statement show the error see the comments?

andy
  • 35
  • 1
  • 6

2 Answers2

5

I would:

  1. Create a type to hold a file name and timestamp.
  2. Use FindFirstFile to get the timestamp you care about for each file.
  3. Create a name/timestamp object and store it into a vector.
  4. Call FindClose for that file.
  5. Repeat from 2 for each input file name.
  6. Sort the vector on the timestamp.
  7. Display the results.

So, one possible implementation might look something like this:

#include <iostream>
#include <Windows.h>
#include <algorithm>
#include <string>
#include <vector>
#include <iomanip>

class file {
    std::string name;
    FILETIME time;
public:
    bool operator<(file const &other) const { 
        return CompareFileTime(&time, &other.time) == 1;
    }

    friend std::ostream &operator<<(std::ostream &os, file const &f) {
        SYSTEMTIME st;
        FileTimeToSystemTime(&f.time, &st);
        return os << std::setw(20) << f.name << "\t" << st.wHour << ":" << st.wMinute << ":" << st.wSecond << " " << st.wYear << "/" << st.wMonth << "/" << st.wDay;
    }

    file(WIN32_FIND_DATA const &d) : name(d.cFileName), time(d.ftCreationTime) {}
};

int main(){ 
    std::vector<std::string> inputs{ "a.txt", "b.txt" };

    std::vector<file> files;

    std::transform(inputs.begin(), inputs.end(), 
        std::back_inserter(files),
        [](std::string const &fname) {
            WIN32_FIND_DATA d;
            HANDLE h = FindFirstFile(fname.c_str(), &d);
            FindClose(h);
            return d;
        }
    );

    std::sort(files.begin(), files.end());
    std::copy(files.begin(),files.end(),
        std::ostream_iterator<file>(std::cout, "\n"));
}

To deal with "wide" (Unicode) strings for the file names, you'd modify that (slightly) to look something like this:

#include <iostream>
#include <Windows.h>
#include <algorithm>
#include <string>
#include <vector>
#include <iomanip>

class file {
    std::wstring name;
    FILETIME time;
public:
    bool operator<(file const &other) const { 
        return CompareFileTime(&time, &other.time) == 1;
    }

    friend std::wostream &operator<<(std::wostream &os, file const &f) {
        SYSTEMTIME st;
        FileTimeToSystemTime(&f.time, &st);
        return os << std::setw(20) << f.name << L"\t" << st.wHour << L":" << st.wMinute << L":" << st.wSecond << L" " << st.wYear << L"/" << st.wMonth << L"/" << st.wDay;
    }

    file(WIN32_FIND_DATA const &d) : name(d.cFileName), time(d.ftCreationTime) {}
};

int main(){ 
    std::vector<std::wstring> inputs{ L"a.txt", L"b.txt" };

    std::vector<file> files;

    std::transform(inputs.begin(), inputs.end(), 
        std::back_inserter(files),
        [](std::wstring const &fname) {
            WIN32_FIND_DATA d;
            HANDLE h = FindFirstFile(fname.c_str(), &d);
            FindClose(h);
            return d;
        }
    );

    std::sort(files.begin(), files.end());
    for (auto const &f : files)
        std::wcout << f << L"\n";
}

Then when you build it you need to tell the compiler you want the Unicode versions of the Windows functions by defining UNICODE when you compile:

cl -DUNICODE files.cpp
Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
  • Jerry Coffin I try to do this for last 6 days. I try many things. Please help me to do that? – andy May 05 '15 at 03:49
  • @andy: What part do you need help with? – Jerry Coffin May 05 '15 at 03:54
  • Sir, Where i put folder path or allFiles? – andy May 05 '15 at 05:44
  • @andy: The `inputs` vector in `main` holds the names of the files to be listed. – Jerry Coffin May 05 '15 at 05:48
  • error. 1 IntelliSense: no instance of constructor "std::basic_string<_Elem, _Traits, _Alloc>::basic_string [with _Elem=char, _Traits=std::char_traits, _Alloc=std::allocator]" matches the argument list argument types are: (const WCHAR [260]) c:\Users\Administrator\Desktop\2015.5.5\Keep Recent\Try to make Full\Still Doing 1\File Remover Test 11\File Remover Test 11\Search.h 102 39 File Remover Test 11 – andy May 05 '15 at 05:50
  • 2nd error. 2 IntelliSense: argument of type "const char *" is incompatible with parameter of type "LPCWSTR" c:\Users\Administrator\Documents\Visual Studio 2013\Projects\Test\Test\Test.cpp 465 28 Test – andy May 05 '15 at 05:51
  • Sir, How to save sort file in CString or CStringArray and display in textbox? – andy May 05 '15 at 06:42
  • @andy this is altogether a different question.Please post a new question so that it will be useful for other people looking for similar solution. – GingerJack May 05 '15 at 08:36
  • I try to save sort files in Array see what happen. – andy May 05 '15 at 08:51
  • files.insert(files.begin(), &allFiles[0], &allFiles[allFiles.GetSize() - 1] + 1); Error 13 error C2664: 'file::file(const file &)' : cannot convert argument 1 from 'CString' to 'const WIN32_FIND_DATA &' c:\program files (x86)\microsoft visual studio 12.0\vc\include\xmemory0 600 1 File Remover Test 11 – andy May 05 '15 at 08:52
0

Simple way to sort file based on creation date or last write date is store the files in to a map where Key is the date and value is the file name. Map will sort it for you.. my code example as below..

BOOL GetLastWriteTime(FILETIME ftWrite, LPWSTR lpszString, DWORD dwSize)
{
     DWORD dwRet;
     SYSTEMTIME st, stLocal;
    // Convert the last-write time to local time.
    FileTimeToSystemTime(&ftWrite, &st);
    SystemTimeToTzSpecificLocalTime(NULL, &st, &stLocal);

    // Build a string showing the date and time.
    dwRet = StringCchPrintf(lpszString, dwSize, 
        TEXT("%02d%02d%d%02d%02d%02d%04d"),
        stLocal.wMonth, stLocal.wDay, stLocal.wYear,
        stLocal.wHour, stLocal.wMinute, stLocal.wSecond, stLocal.wMilliseconds);

    if( S_OK == dwRet )
        return TRUE;
    else return FALSE;
}


int _tmain(int argc, _TCHAR* argv[])
{
    std::map<wstring, wstring> first;

     wstring directory = L"D:\\SourceCode\\FilesTemp\\*";
     std::wstring name;
     WCHAR szBuf[MAX_PATH];
     WIN32_FIND_DATA d;
     HANDLE hFindFile   = FindFirstFile ( directory.c_str(), &d );

     if (hFindFile == INVALID_HANDLE_VALUE) 
    {
        DWORD dwLastError = ::GetLastError();

        if( dwLastError != ERROR_NO_MORE_FILES &&
            dwLastError != ERROR_FILE_NOT_FOUND)
        {
            return FALSE;
        }

        // No files found
        return TRUE;
    }
     do
     {
         if( d.cFileName[0] &&  _tcscmp( d.cFileName, _T( "." )) != 0 &&_tcscmp( d.cFileName, _T( ".." )) != 0 )
         {
             name = d.cFileName;
             if(GetLastWriteTime( d.ftLastWriteTime, szBuf, MAX_PATH ))
             {
                _tprintf(TEXT("Last write time is: %s\n"), szBuf);
                first[szBuf] = name;
             }
         }
     }while (FindNextFile ( hFindFile, &d ));

    return 0;
}
  • Won't this fail if two files have the same date? – fsanches Jul 05 '19 at 19:59
  • i was trying to use this code but it gives me [C++ Error] Unit1.cpp(39): E2303 Type name expected and if i use StringCchPrintf or sprintf didn't allow me to use them for [C++ Error] Unit1.cpp(31): E2268 Call to undefined function 'sprintf'.... – codroipo May 22 '20 at 11:33