Trying to read files in directory, directory just leads to himself and loops in himself

Viewed 39

So the code idea is as following: i pick a path in the main, go in it, if i encounter a file, just save its name and modification date in the .txt file, otherwise it should open the directory it just found, get inside and re-do the process for this directory

The rest of the process works quite fine, UNTIL i uncomment the recursive part, where it will proceed to go in itself i think (Path.), then loops to that state (go to Path.., Path... , etc), making the thing completely useless and justan infinite loop

Any ideas?

#include <dirent.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/types.h>

void ecrire(char * s);
void ecrire_add(char * s);
void regarder(char * loc);

int main(void) {
    char localisation[10000]="Path example";
    ecrire("");
    regarder(localisation);
  return(0);
}

void ecrire_add(char * s){
    FILE * fichiertexte;
    fichiertexte = fopen(".\\liste.txt","a");
    fputs(s,fichiertexte);
    fclose(fichiertexte);
}
void ecrire(char * s){
    FILE * fichiertexte;
    fichiertexte = fopen(".\\liste.txt","w");
    fprintf(fichiertexte,s);
    fclose(fichiertexte);
}

void regarder(char * loc){
    DIR *d;
    struct dirent *dir;
    char contenu[100];
    char position[100];
    char modification[20];
    struct stat attrib;
    d = opendir(loc);
    strcpy(position, loc);
    if (d) {
    while ((dir = readdir(d)) != NULL) {
        if((dir->d_name) !="$WinREAgent" && (dir->d_name) !=".." && (dir->d_name) !="." && (dir->d_name) !="\\."){
            strcpy(contenu,dir->d_name);
            strcat(position,"\\");
            strcat(position,contenu);
            stat(position,&attrib);
            strftime(modification, 20, "%H:%M:%S %d-%m-%y", localtime(&(attrib.st_mtime)));
            //where i think the problem starts
            //this is the part i comment to check if the rest is functionnal
            if((S_ISDIR(attrib.st_mode)) && (dir->d_name) !=loc){
                printf("rentre doss %s \n", position);
                regarder(position);
            }
            //where i think it ends
            printf("%s \n", position);
            strcat(position,"\n");
            strcat(position,modification);
            strcat(position,"\n \n");
            ecrire_add(position);
            strcpy(position,loc);
            strcpy(modification,"");
        }
    }
  }
  closedir(d);
}
2 Answers

The problem is here:

if((dir->d_name) !="$WinREAgent" && (dir->d_name) !=".." && (dir->d_name) !="." && (dir->d_name) !="\\.")

In C, comparing strings with == or != compares the addresses of the two strings, not their contents. Since string literals are in the program's static data area and d_name points either to malloced memory or to a scratch buffer inside the DIR object, these comparisons will always be false. You have to use strcmp instead. Also, the name of the special directory entry . is just ., not \.. Thus:

if (!strcmp(dir->d_name, "$WinREAgent") ||
    !strcmp(dir->d_name, "..") ||
    !strcmp(dir->d_name, ".")) {
    continue;
}
// what you had inside your if statement goes here

Note that I flipped the sense of the if. This is just to avoid another level of indentation.

Since you appear to be using Windows, you may want to use strcasecmp for the first of these comparisons. You may also want to use the native Windows API for scanning directories (FindFirstFileW/FindNextFileW) instead of the Unix compatibility layer, for better support for non-ASCII filenames (but it's a big change to make).

I did not check your code for other problems.

(dir->d_name) !=".." is not a valid way to check if dir->d_name is equal to the string "..". You need to use strcmp(dir->d_name, "..");

The string literal ".." refers to a location in memory which contains the 3 bytes ., ., and \0. It is entirely possible for dir->d_name to also contain those same bytes, but since it is in a different place dir->d_name == ".." will be false. But strcmp(dir->d_name, "..") will evaluate to zero if the contents of the two locations are the same.

Related