Reputation: 1299
I have a function that takes in a filename (string) and I want to have an array of filenames (strings) to check to see if the filename taht was passed in is in the array and if not add it to it. Here is what I got so far.
bool read_file(char * filename, bool warnings){
//Check to see if filename is in array files
static char * files[MAXFILES];
static int counter = 0;
for(int i=0;i<counter;i++){
if(strcmp(filename,files[i]) == 0){
fprintf(stdout, "Error\n");
return 0;
}
else{
files[counter]=filename;
counter++;
}
}
FILE * fp = fopen(filename,"r");
if(fp == NULL){
if(warnings){
fprintf(stderr, "Can't open the file %s\n",filename);
return 0;
}
else{
return 0;
}
}
else{
fclose(fp);
fp = NULL;
return 1;
}
}
For some reason it wont add filenames to files[] any help would be appricated.
Upvotes: 2
Views: 132
Reputation: 11162
Your else
is misplaced. This:
for(int i=0;i<counter;i++){
if(strcmp(filename,files[i]) == 0){
fprintf(stdout, "Error\n");
return 0;
}
else{
files[counter]=filename;
counter++;
}
}
Will never be entered, and were it to be, it would always think that the file was in the list, because you append it before you finish checking. You would then find the one you appended, and think it was already there.
Instead, wait until you've finished checking the whole list until you append the filename:
for(int i=0;i<counter;i++){
if(strcmp(filename,files[i]) == 0){
fprintf(stdout, "Error\n");
return 0;
}
}
files[counter]=filename;
counter++;
The key is that the return 0
redirects the flow out of your function, rather than an else clause. You know that as long as the loop finishes and you're still in the function that the filename isn't there yet.
Upvotes: 1
Reputation: 753695
Look at the else
clause of this loop:
for(int i=0;i<counter;i++){
if(strcmp(filename,files[i]) == 0){
fprintf(stdout, "Error\n");
return 0;
}
else{
files[counter]=filename;
counter++;
}
}
You want to add the file to the list only once you know it is not in the list, and you won't know that until you have gone through the entire list. So, that code should probably look like:
for (int i = 0; i < counter; i++)
{
if (strcmp(filename, files[i]) == 0)
{
fprintf(stdout, "Duplicate file %s found at %d\n", filename, i);
return 0;
}
}
files[counter++] = filename;
Notice the better error message than just 'Error'. You will need to know what went wrong because this won't be the only place in the program where there could be errors. You can debate whether the number is helpful; the name most certainly is, but having the index number might help you too.
Upvotes: 1
Reputation: 46423
Take a look at the first time through your loop (when i == 0
and counter == 0
):
static int counter = 0;
for(int i = 0; i < counter; i++) {
// this never runs
}
i < counter
is always false, because counter
is incremented in the body of the for loop.
You'll need to rethink your logic. This function is doing a lot of stuff. Maybe something like this infront of the loop will help:
if (counter == 0) {
// first time in the function, just add the filename
files[counter]=filename;
counter++;
}
else {
for (int i = 0; i < counter; i++) {
...
}
}
However, you might have better luck splitting this into a couple functions. One to add a filename to the array, another to check if it's already there, a third to open the file, etc.
Upvotes: 1