File size distribution: Difference between revisions

Added C solution
m (Minor edit to C++ code)
(Added C solution)
Line 152:
</pre>
Note that it is possible to track files up to 10^24 (Yottabyte) in size with this implementation, but if you have a file that large, you shouldn't be needing such programs. :)
 
===POSIX===
{{libheader|POSIX}}
This works on macOS 10.15. It should be OK for Linux as well.
<lang c>#include <ftw.h>
#include <locale.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
 
static const uintmax_t sizes[] = {
0, 1000, 10000, 100000, 1000000, 10000000,
100000000, 1000000000, 10000000000
};
static const size_t nsizes = sizeof(sizes)/sizeof(sizes[0]);
static uintmax_t count[nsizes + 1] = { 0 };
static uintmax_t files = 0;
static uintmax_t total_size = 0;
 
static int callback(const char* file, const struct stat* sp, int flag) {
if (flag == FTW_F) {
uintmax_t file_size = sp->st_size;
++files;
total_size += file_size;
size_t index = 0;
for (; index <= nsizes && sizes[index] < file_size; ++index);
++count[index];
} else if (flag == FTW_DNR) {
fprintf(stderr, "Cannot read directory %s.\n", file);
}
return 0;
}
 
int main(int argc, char** argv) {
setlocale(LC_ALL, "");
const char* directory = argc > 1 ? argv[1] : ".";
if (ftw(directory, callback, 512) != 0) {
perror(directory);
return EXIT_FAILURE;
}
printf("File size distribution for '%s':\n", directory);
for (size_t i = 0; i <= nsizes; ++i) {
if (i == nsizes)
printf("> %'lu", sizes[i - 1]);
else
printf("%'16lu", sizes[i]);
printf(" bytes: %'lu\n", count[i]);
}
printf("Number of files: %'lu\n", files);
printf("Total file size: %'lu\n", total_size);
return EXIT_SUCCESS;
}</lang>
 
{{out}}
<pre>
File size distribution for '.':
0 bytes: 0
1,000 bytes: 3
10,000 bytes: 111
100,000 bytes: 2,457
1,000,000 bytes: 2,645
10,000,000 bytes: 2,483
100,000,000 bytes: 172
1,000,000,000 bytes: 3
10,000,000,000 bytes: 0
> 10,000,000,000 bytes: 0
Number of files: 7,874
Total file size: 11,963,566,673
</pre>
 
=={{header|C++}}==
1,777

edits