Listing files by last write time

Started by
12 comments, last by szecs 14 years, 1 month ago
A want to list files by their last write time. I separate the file names (without extensions) with a newline character. Problem: sorting is not good, otherwise works fine (returns exact file number, cuts extensions fine, handles no files fine, adds newlines fine) Code:
int ListSaveFiles(char *out)
{
	int fileNumber = 1;

	WIN32_FIND_DATA findFileData[20];
	int index[20];
	HANDLE hFind = FindFirstFile((LPCSTR)"*.sav", &findFileData[0]);

	*out = '\0';

	if( hFind  == INVALID_HANDLE_VALUE )
		return 0;
	while( fileNumber < 20 && FindNextFile(hFind, &findFileData[fileNumber]) )
		fileNumber++;

	FindClose(hFind);

	for( int i = 0; i < fileNumber; i++ )
		index = i;

	for( int i = 0; i < fileNumber-1; i++ )
	{
		for( int k = i+1; k < fileNumber; k++ )
		{	
			int store;

			if( findFileData[k].ftLastWriteTime.dwHighDateTime < 
				findFileData.ftLastWriteTime.dwHighDateTime )
			{
				store = index;
				index = index[k];
				index[k] = store;
			}
			else if( findFileData[k].ftLastWriteTime.dwHighDateTime ==
				findFileData.ftLastWriteTime.dwHighDateTime
				&& findFileData[k].ftLastWriteTime.dwLowDateTime <
				findFileData.ftLastWriteTime.dwLowDateTime )
			{
				store = index;
				index = index[k];
				index[k] = store;
			}
		}
	}

	strncpy(out,&findFileData[index[0]].cFileName[0],
			strlen(&findFileData[index[0]].cFileName[0])-4);
	out[strlen(&findFileData[index[0]].cFileName[0])-4] = '\0';

	for( int i = 1; i < fileNumber; i++ )
	{
		strcat(out,"\n");
		strncat(out,&findFileData[index].cFileName[0],
			strlen(&findFileData[index].cFileName[0])-4);
	}

	return fileNumber;
}
My guesses:
  • I can't make bubble sort
  • I can't swap 2 values
  • some other idiotic bug
  • I misunderstood the high, low time parts
  • Resolution of the write time isn't good enough (NTFS) Don't critique the code, I want to make it work first. Maybe I should store the exact time in the file? Thanks for answers in advance!
  • Advertisement
    Your handling of the file timestamp structure is incorrect. Compare with this example.

    Also, your code itself is highly problematic. I won't get into details since you asked for no critiques on the code, but there's a few much safer and simpler ways to get at what you want to do [smile]

    Wielder of the Sacred Wands
    [Work - ArenaNet] [Epoch Language] [Scribblings]

    Quote:Original post by ApochPiQ
    Your handling of the file timestamp structure is incorrect. Compare with this example.

    Also, your code itself is highly problematic. I won't get into details since you asked for no critiques on the code, but there's a few much safer and simpler ways to get at what you want to do [smile]
    Okay, maybe I would accept some critique too...

    I saw that example, but I though it's easier to work with two values, instead of all the date/time stuff.

    Or maybe I could convert it to a string (as in the example), and do a lexical sort?

    (I know that strcat/strcopy etc has a safer version too.)
    Why not just use the CompareFileTime function directly? You can wrap CompareFileTime into a comparison predicate and then use std::multimap to order the files for you based on their relative timestamps.

    Wielder of the Sacred Wands
    [Work - ArenaNet] [Epoch Language] [Scribblings]

    Yup, I haven't have to much sleep.

    Thanks for that (I have no idea why I didn't think, that this comparison is common enough to have its own function)
    Nope.
    CompareFileTime gives exactly the same results. I exit and run the program before I make the comparison (and use fclose too), so I'm not comparing opened files.

    Code:
    int ListSaveFiles(char *out){	int fileNumber = 1;	WIN32_FIND_DATA findFileData[20];	int index[20];	HANDLE hFind = FindFirstFile((LPCSTR)"*.sav", &findFileData[0]);	*out = '\0';	if( hFind  == INVALID_HANDLE_VALUE )		return 0;	while( fileNumber < 20 && FindNextFile(hFind, &findFileData[fileNumber]) )		fileNumber++;	FindClose(hFind);	for( int i = 0; i < fileNumber; i++ )		index = i;	for( int i = 0; i < fileNumber-1; i++ )	{		for( int k = i+1; k < fileNumber; k++ )		{				int store;			if( CompareFileTime(&findFileData[k].ftLastWriteTime,					&findFileData.ftLastWriteTime) > 0 )			{				store = index;				index = index[k];				index[k] = store;			}		}	}	strncpy(out,&findFileData[index[0]].cFileName[0],			strlen(&findFileData[index[0]].cFileName[0])-4);	out[strlen(&findFileData[index[0]].cFileName[0])-4] = '\0';	for( int i = 1; i < fileNumber; i++ )	{		strcat(out,"\n");		strncat(out,&findFileData[index].cFileName[0],			strlen(&findFileData[index].cFileName[0])-4);	}	return fileNumber;}


    File write:
    ...
    fp = fopen(filename_ext,"wb");
    ...
    fclose(fp);


    I use C, and I don't know how to use std.
    I still don't know what can be the problem. Thanks
    Sorry guys, I still have no idea about this one. Last effort, last bump. Thanks.
    I think the sorting is incorrect. You should use the indices in the 'index' array when comparing the entries in 'findFileData'. Something like:

    for( int i = 0; i < fileNumber-1; i++ ){	for( int k = i+1; k < fileNumber; k++ )	{			int store;		if( CompareFileTime(&findFileData[index[k]].ftLastWriteTime,				&findFileData[index].ftLastWriteTime) > 0 )		{			store = index;			index = index[k];			index[k] = store;		}	}}
    Yes.

    No matter how long I'm staring at a code, how many times I start a new task/go for a walk/sleep/whatever, if I don't see the obvious, the I don't see the obvious.

    [embarrass]

    Thanks for helping out one of your blind fellow-beings.

    This topic is closed to new replies.

    Advertisement