如何使用C循环遍历文件夹中的所有文件?

hs1rzwqc  于 2023-01-25  发布在  其他
关注(0)|答案(7)|浏览(176)

我想从目录中的所有文件名中删除一个特定的子字符串:
--比如《飞出个未来》第一XYZ.com季第20集的“www.example.com”--
所以基本上我需要给这个方法提供一个想要的子字符串,它必须循环遍历所有的文件名并进行比较。
我想不出如何使用C循环遍历文件夹中的所有文件。

kzipqqlq

kzipqqlq1#

#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>

int main(int argc, char** argv)
{
 struct dirent *dp;
 DIR *dfd;

 char *dir ;
 dir = argv[1] ;

 if ( argc == 1 )
 {
  printf("Usage: %s dirname\n",argv[0]);
  return 0;
 }

 if ((dfd = opendir(dir)) == NULL)
 {
  fprintf(stderr, "Can't open %s\n", dir);
  return 0;
 }

 char filename_qfd[100] ;
 char new_name_qfd[100] ;

 while ((dp = readdir(dfd)) != NULL)
 {
  struct stat stbuf ;
  sprintf( filename_qfd , "%s/%s",dir,dp->d_name) ;
  if( stat(filename_qfd,&stbuf ) == -1 )
  {
   printf("Unable to stat file: %s\n",filename_qfd) ;
   continue ;
  }

  if ( ( stbuf.st_mode & S_IFMT ) == S_IFDIR )
  {
   continue;
   // Skip directories
  }
  else
  {
   char* new_name = get_new_name( dp->d_name ) ;// returns the new string
                                                   // after removing reqd part
   sprintf(new_name_qfd,"%s/%s",dir,new_name) ;
   rename( filename_qfd , new_name_qfd ) ;
  }
 }
}

尽管我个人更喜欢这样的剧本

#!/bin/bash -f
dir=$1
for file in `ls $dir`
do
 if [ -f $dir/$file ];then
  new_name=`echo "$file" | sed s:to_change::g`
  mv $dir/$file $dir/$new_name
 fi
done
mwg9r5ms

mwg9r5ms4#

关键函数是_findfirst、_findnext和_findclose

struct _finddata_t file_info;
char discard[] = "XYZ.com";
char dir[256] = "c:\\folder\\";
char old_path[256];
char new_path[256];
intptr_t handle = 0;

memset(&file_info,0,sizeof(file_info));

strcpy(old_path,dir);
strcat(old_path,"*.avi");

handle = _findfirst(old_path,&file_info);
if (handle != -1)
{
    do
    {
        char *new_name = NULL;
        char *found = NULL;
        new_name = strdup(file_info.name);
        while ((found = strstr(new_name,discard)) != 0)
        {
            int pos = found - new_name;
            char* temp = (char*)malloc(strlen(new_name));
            char* remain = found+strlen(discard);
            temp[pos] = '\0';
            memcpy(temp,new_name,pos);
            strcat(temp+pos,remain);
            memcpy(new_name,temp,strlen(new_name));
            free(temp);
        }
        strcpy(old_path,dir);
        strcat(old_path,file_info.name);
        strcpy(new_path,dir);
        strcat(new_path,new_name);
        rename(old_path,new_path);
        free(new_name);
    }while(_findnext(handle,&file_info) != -1);
}
    _findclose(handle);
e0uiprwp

e0uiprwp5#

我知道这个答案会让我被否决,但是你的问题对于shell脚本(或.cmd脚本)、PHP脚本或Perl脚本来说是完美的,用C做这个问题比这个问题所需要的工作要多。

vbopmzt1

vbopmzt16#

fts有一个很好的接口,但是它是4.4BSD,而且不可移植。(我最近被一些固有地依赖于fts的软件咬了一口。)opendirreaddir没有那么有趣,但是它们是POSIX标准,并且是可移植的。

ifmq2ha2

ifmq2ha27#

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

#include <dirent.h>

int read_directories(const char* path) {
    DIR* directory = NULL;
    if ((directory = opendir(path)) == NULL) {
        fprintf(stderr, "Can't open %s\n", path);
        return EXIT_FAILURE;
    }

    struct dirent* entry = NULL;
    while ((entry = readdir(directory)) != NULL) {
        char full_name[256] = { 0 };
        snprintf(full_name, 100, "%s/%s", path, entry->d_name);

        if (entry->d_type == DT_DIR) {
            printf("'%s' is a directory\n", full_name);
            // Recurse unless the directory is the current or parent directory.
            if (strcmp(entry->d_name, ".") != 0 && strcmp(entry->d_name, "..") != 0) {
                return read_directories(full_name);
            }
        } else {
            printf("'%s' is a file\n", full_name);
        }
    }

    closedir(directory);
    return EXIT_SUCCESS;
}

int main(int argc, const char* const argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Must provide a single path as argument!\n");
        return EXIT_FAILURE;
    }

    const char* path = argv[1];
    return read_directories(path);
}

在终端中运行可执行文件的示例:

./main .

相关问题