Two Solutions to Problem 3, page 270 of Perry, John. "Advanced C Programming by Example" Belmont, CA: PWS Publishing, 1998.
The first copies the strings.
The second reuses the pointers in the array passes to it.
// | |
// Created by Noah Cardoza on 2019-03-21. | |
// | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <stdio.h> | |
#include <assert.h> | |
/** | |
* verifies that an array of files exists | |
* @param filenames a double array of | |
* pointers to c-strings | |
* @return a subset of filenames only | |
* including files that exist | |
*/ | |
char **checkDelete(char **filenames) { | |
// a pointer used to traverse filenames | |
char *filename = NULL; | |
// contains all the files that exist | |
char **existing_files = NULL; | |
// the number of files found | |
int found = 0; | |
// in the case where there are no valid | |
// filenames we need to still return a | |
// NULL terminated char* array | |
existing_files = (char**)malloc(sizeof(char*)); | |
assert(existing_files); // assure the malloc was successful | |
*existing_files = NULL; | |
while ((filename = *filenames)){ | |
// returns -1 if the filename is not "ok" aka not readable/writable/non-existent | |
if(access(filename, F_OK) != -1) { | |
// add 2 because we need a null terminator | |
existing_files = (char**)realloc(existing_files, (found + 2) * sizeof(char*)); | |
assert(existing_files); // assure the realloc was successful | |
// reuses the pointers passes to it | |
existing_files[found - 1] = filename; | |
existing_files[found + 1] = NULL; | |
found += 1; | |
} | |
filenames++; | |
} | |
return existing_files; | |
} | |
int main(void){ | |
char **ptr, **head; | |
char *files[80] = { | |
"main.c", | |
"test_file/that/does/not.exist", | |
"ec03", | |
"ec03/EC_Tables.c", | |
"hw04", | |
"non.existent", | |
NULL | |
}; | |
head = ptr = checkDelete(files); | |
while (*ptr) { | |
printf("%s\n", *ptr); | |
ptr++; | |
} | |
free(head); | |
return 0; | |
} | |
/* Output: | |
* main.c | |
* ec03 | |
* ec03/EC_Tables.c | |
* hw04 | |
*/ |
/
main.c
ec03/
EC_Tables.c
INPUT.TXT
hw04/
// | |
// Created by Noah Cardoza on 2019-03-21. | |
// St | |
// | |
#include <unistd.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <stdio.h> | |
#include <assert.h> | |
/** | |
* verifies that an array of files exists | |
* @param filenames a double array of | |
* pointers to c-strings | |
* @return a subset of filenames only | |
* including files that exist | |
*/ | |
char **checkDelete(char **filenames) { | |
// a pointer used to traverse filenames | |
char *filename = NULL; | |
// contains all the files that exist | |
char **existing_files = NULL; | |
// the number of files found | |
int found = 0; | |
// in the case where there are no valid | |
// filenames we need to still return a | |
// NULL terminated char* array | |
existing_files = (char**)malloc(sizeof(char*)); | |
assert(existing_files); // assure the malloc was successful | |
*existing_files = NULL; | |
while ((filename = *filenames)){ | |
// returns -1 if the filename is not "ok" aka not readable/writable/non-existent | |
if(access(filename, F_OK) != -1) { | |
// add 2 because we need a null terminator | |
existing_files = (char**)realloc(existing_files, (found + 2) * sizeof(char*)); | |
assert(existing_files); // assure the realloc was successful | |
existing_files[found] = (char*)malloc((strlen(filename) + 1) * sizeof(char)); | |
assert(existing_files[found]); // assure the malloc was successful | |
// copy the string so it can be safely mutated later | |
strcpy(existing_files[found], filename); | |
existing_files[found + 1] = NULL; | |
found += 1; | |
} | |
filenames++; | |
} | |
return existing_files; | |
} | |
int main(void){ | |
char **ptr, **head; | |
char *files[80] = { | |
"main.c", | |
"test_file/that/does/not.exist", | |
"ec03", | |
"ec03/EC_Tables.c", | |
"hw04", | |
"non.existent", | |
NULL | |
}; | |
head = ptr = checkDelete(files); | |
while (*ptr) { | |
printf("%s\n", *ptr); | |
free(*ptr); | |
ptr++; | |
} | |
free(head); | |
return 0; | |
} | |
/* Output: | |
* main.c | |
* ec03 | |
* ec03/EC_Tables.c | |
* hw04 | |
*/ |