directory - 如何使用 qsort 根据字节对包含路径名/文件的字符进行排序?

标签 directory sorting c

我基本上写了一个代码,其中我接受两个命令行参数,一个是我想在我的目录中搜索的文件类型,另一个是我想要的数量(尚未实现,但我可以解决这个问题) 代码是这样的:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

#define sizeFileName 500
#define filesMax 5000

int cmpfunc( const void *a, const void *b) {
  return *(char*)a + *(char*)b;
}

int main( int argc, char ** argv) {
  FILE * fp = popen( "find . -type f", "r");
  char * type = argv[1];
  char * extension = ".";

  char* tExtension;
  tExtension = malloc(strlen(type)+1+4);
  strcpy(tExtension, extension);
  strcat(tExtension, type);
  // printf("%s\n",tExtension);

  int amount = atoi(argv[2]);
  //printf("%d\n",amount);

  char buff[sizeFileName];
  int nFiles = 0;
  char * files[filesMax];
  while(fgets(buff,sizeFileName,fp)) {
    int leng = strlen(buff) - 1;
    if (strncmp(buff + leng - 4, tExtension, 4) == 0){
      files[nFiles] = strndup(buff,leng);
      //printf("\t%s\n", files[nFiles]);
      nFiles ++;
    }
  }
  fclose(fp);
  printf("Found %d files\n", nFiles);

  long long totalBytes = 0;
  struct stat st;

  // sorting based on byte size from greatest to least
  qsort(files, (size_t) strlen(files), (size_t) sizeof(char), cmpfunc);

  for(int i = 0;i< nFiles; i ++) {
    if(0!= stat(files[i],&st)){
      perror("stat failed:");
      exit(-1);
    }
    totalBytes += st.st_size;
    printf("%s : %ld\n",files[i],st.st_size);
  }
  printf("Total size: %lld\n", totalBytes);
  // clean up
  for(int i = 0; i < nFiles ; i ++ ) {
    free(files[i]);
 }
  return 0;
}

到目前为止,我已经正确设置了每个部分,在运行代码时说 $./find ini 5, 它将打印出所有 ini 文件,然后是它们的字节大小(目前忽略 5)。但是,对于 qsort(),我不确定如何对 char * files 的内容进行排序,因为当它包含路径名时,我不得不使用 stat 以获取字节大小,我如何打印出我的打印语句的排序版本,其中第一个语句是最多的字节,并且以最少的字节结束?

最佳答案

如果我们假设您的输入有效,您的问题可以简化为:

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

#define filesMax 5000

int cmpfunc(const void const *a, const void *b) { return *(char *)a + *(char *)b; }

int main(void) {
  int nFiles = 4;
  char *files[filesMax] = {"amazing", "hello", "this is a file", "I'm a bad file"};
  qsort(files, strlen(files), sizeof(char), cmpfunc);

  for (int i = 0; i < nFiles;; i++) {
    printf("%s\n", files[i]);
  }
}

如果编译时出现警告:

source_file.c:11:23: warning: incompatible pointer types passing 'char *[5000]' to parameter of type 'const char *' [-Wincompatible-pointer-types]
  qsort(files, strlen(files), sizeof(char), cmpfunc);
                      ^~~~~

qsort() 需要数组的大小(或者在您的情况下是子大小),并且还需要数组中一个元素的大小。在这两种情况下,你都错误地把它给了它。此外,您的比较函数不比较任何内容,您目前正在添加 char 的两个指针的第一个字节,这没有多大意义。

要修复您的代码,您必须编写:

qsort(files, nFiles, sizeof *files, &cmpfunc);

同时修正你的比较函数:

int cmpfunc_aux(char * const *a, char * const *b) { return strcmp(*a, *b); }

int cmpfunc(void const *a, void const *b) { return cmpfunc_aux(a, b); }

size 也应该是 size_t 类型:

size_t nFiles = 0;

不要忘记所有关于如何使用函数的信息都写在他们的doc中。 .


how would I print out a sorted version of my print statements featuring the first statement being the most bytes and finishes at the least bytes?

您的代码没有显示您正在尝试这样做的任何线索,您目前正在存储名称文件,而且仅此而已。您希望如何使用未获取的信息对文件进行排序?

然而,创建一个包含文件名和大小的结构,获取对其进行排序所需的信息并对其进行排序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <inttypes.h>

struct file {
  off_t size;
  char *name;
};

int cmpfunc_aux(struct file const *a, struct file const *b) {
  if (a->size > b->size) {
    return -1;
  } else if (a->size < b->size) {
    return 1;
  } else {
    return 0;
  }
}

int cmpfunc(void const *a, void const *b) { return cmpfunc_aux(a, b); }

#define filesMax 5000

int main(void) {
  size_t nFiles = 4;
  struct file files[filesMax] = {{42, "amazing"},
                                 {21, "hello"},
                                 {168, "this is a file"},
                                 {84, "I'm a bad file"}};
  qsort(files, nFiles, sizeof *files, &cmpfunc);

  for (size_t i = 0; i < nFiles; i++) {
    printf("%s, %" PRId64 "\n", files[i].name, (intmax_t)files[i].size);
  }
}

关于directory - 如何使用 qsort 根据字节对包含路径名/文件的字符进行排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52734032/

相关文章:

c - 缓冲区溢出漏洞 : Why does "jmp esp" need to be located in a DLL?

powershell - 如何在 PowerShell 的 Get-ChildItem -Exclude cmdlet 中对目录使用通配符

python - 对字典的元组进行排序

xslt - xsl :sort: sorting by numeric value

php - MySQL 查询用数字排序

c - 如何使用RL_ARM lib来设计TCP项目

java - Android System.loadLibrary 崩溃

android - 我的可绘制文件夹在哪里?

oracle - 如何检索 Oracle 目录路径?

c#-4.0 - 在调试或发布控制台应用程序中创建文件夹