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