listing files in a folder using C in Windows

ⅰ亾dé卋堺 提交于 2021-02-05 09:38:07

问题


I want to list the files in this folder "C:\home\WORK\Desktop\Communication". There are ten files in this folder. My code has no error but it's not printing anything. What is my mistake ?

#include<stdio.h>
#include<Windows.h>
#include<string.h>

int main(int argc,char *argv[])
{
  char path[]="C:\\home\\WORK\\Desktop\\Communication";
  strcat_s(path,sizeof(path),"\\*");

  WIN32_FIND_DATA fdata;
  HANDLE hFind =INVALID_HANDLE_VALUE;
  int numberOfFiles=0;
  char *files[10];

 hFind = FindFirstFile(path,&fdata);

 while((FindNextFile(hFind,&fdata))!=0)
   {
     files[numberOfFiles]=fdata.cFileName;
     numberOfFiles++;
     printf("%s\n",files[numberOfFiles]);

   }

   FindClose(hFind);

  return 0;
}

回答1:


There are a few things wrong with your code.

  1. strcat_s can't append "\\*" to your path char array. The buffer only has enough room for storing the string literal.
  2. I'm uncomfortable with letting you declare a buffer files that has only enough memory to fit all the file names. What happens if you add one more file? Then the buffer is overrun. However, it will still technically work in this scenario.
  3. This line printf("%s\n",files[numberOfFiles]); is undefined behavior. You incremented numberOfFiles to a location in the array that has not been initialized, so it's not going to print the file name.
  4. When you call FindClose, you invalidate all of those pointers that you stored in files. You can no longer use them. You need to copy the string to a new buffer.

The following code works.

#include<stdio.h>
#include<Windows.h>
#include<string.h>

int main(int argc,char *argv[])
{
    char path[] = "C:\\home\\WORK\\Desktop\\Communication\\*.*";
    //strcat_s(path,sizeof(path),"\\*");

    WIN32_FIND_DATA fdata;
    HANDLE hFind =INVALID_HANDLE_VALUE;
    int numberOfFiles=0;
    char* files[10]; /* you may want to expand this buffer */

    hFind = FindFirstFile(path,&fdata);

    while((FindNextFile(hFind,&fdata))!=0)
    {
        size_t len = strlen(fdata.cFileName);
        files[numberOfFiles] = malloc(len + 1 * sizeof*files); // len + 1 for null-terminator
        strcpy_s(files[numberOfFiles], len, fdata.cFileName);

        printf("%s\n",files[numberOfFiles]);
        numberOfFiles++; /* increment this AFTER you print files[numberOfFiles] */
    }

    FindClose(hFind);

    for(int i = 0; i < (sizeof(file)/sizeof(*file)); ++i) {
        free(file[i]);
    }

    return 0;
}



回答2:


Seems, you should move

numberOfFiles++  

past

printf("%s\n",files[numberOfFiles]);

Or

while((FindNextFile(hFind,&fdata))!=0)
{
    files[numberOfFiles]=fdata.cFileName;
    printf("%s\n", files[numberOfFiles++]);
}

Which is same as

while((FindNextFile(hFind,&fdata))!=0)
{
    printf("%s\n", files[numberOfFiles++] = fdata.cFileName);
}

I don't know WinAPI well, but I feel, that all files will contain invalid pointers after FindClose(hFind) as well as all elements of files will point to *(fdata.cFileName) which will be released in FindClose(hFind). In other words, as I understand this, you should copy (or duplicate) fdata.cFileName into files[i] on each iteration.




回答3:


Clear fdata struct after declaring it:

memset( &fdata, 0, sizeof fdata )


来源:https://stackoverflow.com/questions/32799170/listing-files-in-a-folder-using-c-in-windows

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!