patterncMinor
Merge all files in a directory with a specific extension
Viewed 0 times
directoryallwithmergeextensionfilesspecific
Problem
I come from Python, with a bit a FORTRAN and Matlab some years ago.
I'm trying to learn C. My first attempt at a program is one to merge all the files in a directory with a specified extension
```
/*
MERGE: Merges text files. Gives the ability to all files in a
directory with specified extension.
*/
#include
#include
#include
#include
#include
/ Function prototypes /
int append_to_file(const char filename, const char outfilename); // Appends the contents of filename to outfilename
int scandir(char dirname[], char const *ext, char outfile[]); // Scans a directory for files of a specific extension and merges them
bool has_extension(char const name, char const ext);
void usage(); // Prints out usage information (help) to the console
void path_combine(char dest, const char path1, const char *path2); // Combines a directory name and filename to a single filepath
int main(int argc, char *argv[])
{
int nfiles; // Number of files merged
if (argc == 4)
{
nfiles = scandir(argv[1], argv[2], argv[3]);
printf("Merged %d files\n", nfiles);
return 0;
}
else
{
printf("Wrong input, quitting");
return 1;
}
}
int append_to_file(const char filename, const char outfilename)
{
FILE infile, outfile;
char ch;
infile = fopen(filename, "r");
outfile = fopen(outfilename, "a");
if (infile == NULL)
{
printf("Input file is empty, skipping...\n");
return 1;
}
while ((ch = fgetc(infile)) != EOF)
fputc(ch, outfile);
printf("Appended file\n");
fclose(infile);
fclose(outfile);
return 0;
}
int scandir(char dirname[], char const *ext, char outfile[])
/ Scans a directory and merges all files of given extension /
{
DIR *d = NULL;
struct dirent *dir = NULL;
char filepath[strlen(dirname) + 255];
int i = 0;
d = opendir(dirname);
if (d)
{
while ((dir = readdir(d)) != NULL)
{
I'm trying to learn C. My first attempt at a program is one to merge all the files in a directory with a specified extension
```
/*
MERGE: Merges text files. Gives the ability to all files in a
directory with specified extension.
*/
#include
#include
#include
#include
#include
/ Function prototypes /
int append_to_file(const char filename, const char outfilename); // Appends the contents of filename to outfilename
int scandir(char dirname[], char const *ext, char outfile[]); // Scans a directory for files of a specific extension and merges them
bool has_extension(char const name, char const ext);
void usage(); // Prints out usage information (help) to the console
void path_combine(char dest, const char path1, const char *path2); // Combines a directory name and filename to a single filepath
int main(int argc, char *argv[])
{
int nfiles; // Number of files merged
if (argc == 4)
{
nfiles = scandir(argv[1], argv[2], argv[3]);
printf("Merged %d files\n", nfiles);
return 0;
}
else
{
printf("Wrong input, quitting");
return 1;
}
}
int append_to_file(const char filename, const char outfilename)
{
FILE infile, outfile;
char ch;
infile = fopen(filename, "r");
outfile = fopen(outfilename, "a");
if (infile == NULL)
{
printf("Input file is empty, skipping...\n");
return 1;
}
while ((ch = fgetc(infile)) != EOF)
fputc(ch, outfile);
printf("Appended file\n");
fclose(infile);
fclose(outfile);
return 0;
}
int scandir(char dirname[], char const *ext, char outfile[])
/ Scans a directory and merges all files of given extension /
{
DIR *d = NULL;
struct dirent *dir = NULL;
char filepath[strlen(dirname) + 255];
int i = 0;
d = opendir(dirname);
if (d)
{
while ((dir = readdir(d)) != NULL)
{
Solution
-
scandir
It is not a good name for 2 reasons. First, it exists in a global namespace, and second, it doesn't tell what the function does. Your
A perk benefit of using a stock
Yet another benefit of separating responsibilities is that if outfile is in the same directory with source files and it has an target extension, the results could be very strange.
-
has_extension presumes that the extension is always 3 characters. It is not necessarily so. It should calculate an actual length of the
-
append_to_file produces a misleading diagnostics. The
-
path_combine
Contrary to a popular belief, windows understands a forward slash as a path separator (backslash is an artifact of
It is also not necessary to test for last character for being a separator. Just add the separator anyway, it is harmless.
That said, I don't think that you need it at all: just
scandir
It is not a good name for 2 reasons. First, it exists in a global namespace, and second, it doesn't tell what the function does. Your
scandir not only scans the directory, but does an actual merge as well. I would recommend to scan the directory with a standard library's scandir and then merge files (from the list it returns) in a merge function.A perk benefit of using a stock
scandir is an ability to control the merge order. Right now it is unpredictable.Yet another benefit of separating responsibilities is that if outfile is in the same directory with source files and it has an target extension, the results could be very strange.
-
has_extension presumes that the extension is always 3 characters. It is not necessarily so. It should calculate an actual length of the
ext argument.-
append_to_file produces a misleading diagnostics. The
fopen may fail for many reasons, but file being empty is not one of them. Display the error message with perror or strerror.-
path_combine
Contrary to a popular belief, windows understands a forward slash as a path separator (backslash is an artifact of
cmd.exe). There's no need to special case windows.It is also not necessary to test for last character for being a separator. Just add the separator anyway, it is harmless.
That said, I don't think that you need it at all: just
chdir() to the source directory first.Context
StackExchange Code Review Q#66886, answer score: 2
Revisions (0)
No revisions yet.