2010-03-30 8 views
1

J'essaye d'écrire un petit assistant pour Windows qui finira par accepter une extension de fichier comme argument et retourner le nombre de fichiers de ce type dans le répertoire courant. Pour ce faire, je lis les entrées du fichier dans les répertoires et après avoir obtenu l'extension, je voudrais le convertir en minuscules pour le comparer avec l'argument spécifié à ajouter. Lors de la conversion de l'extension en minuscules, j'ai trouvé que toucher même une chaîne dupliquée de la variable d_name provoquerait un comportement étrange, comme aucun autre appel à readdir n'est appelé.Pourquoi toucher "d_name" fait échouer les appels à readdir()?

Voici le code que je utilise en ce moment (le code est commenté préliminaire) et des sorties pour un répertoire donné:

#include <ctype.h> 
#include <dirent.h> 
#include <stdio.h> 
#include <string.h> 

char * strrch(char *string, size_t elements, char character) { 
    char *reverse = string + elements; 
    while (--reverse != string) 
     if (*reverse == character) 
      return reverse; 
    return NULL; 
} 

void test(char *string) { 
    // Even being a duplicate will make it fail: 
    char *str = strdup(string); 
    printf("Strings: %s %s\n", string, str); 
    *str = 'a'; 
    printf("Strings: %s %s\n", string, str); 

    //unsigned short int i = 0; 
    //for (; str[i] != '\0', str++; i++) 
    // str[i] = tolower((unsigned char) str[i]); 
    //puts(str); 
} 

int main(int argc, char **argv) { 
    DIR *directory; 
    struct dirent *element; 

    if (directory = opendir(".")) { 
     while (element = readdir(directory)) 
      test(strrch(element->d_name, element->d_namlen, '.')); 
     closedir(directory); 
     puts(NULL); 
    } else 
     puts("Couldn't open the directory.\n"); 
} 

sortie sans modifier le double (modification et le second printf appel a commenté):

Strings: (null) (null) 
Strings: . . 
Strings: .exe .exe 
Strings: .pdf .pdf 
Strings: .c .c 
Strings: .ini .ini 
Strings: .pdf .pdf 
Strings: .pdf .pdf 
Strings: .pdf .pdf 
Strings: .flac .flac 
Strings: .FLAC .FLAC 
Strings: .lnk .lnk 
Strings: .URL .URL 

sortie du même répertoire (avec le code ci-dessus, avec les 2 printf s):

Strings: (null) (null) 

Y at-il un problème? Est-ce un problème de compilateur? J'utilise GCC 4.4.3 dans Windows (MinGW) dès maintenant.

Merci beaucoup pour votre aide. Par ailleurs, existe-t-il un autre moyen de travailler avec des fichiers et des répertoires dans un environnement Windows n'utilisant pas les fonctions POSIX?

Répondre

2

Sur les systèmes Windows, l'API "native" n'est pas POSIX mais Win32. Avec Win32, essayez FindFirstFile() et FindNextFile(). En ce qui concerne votre code: votre première ligne montre que le premier appel à test() est avec un pointeur NULL (c'est ce que retourne votre fonction strrch() pour un nom de fichier de "."). strdup() est assez aimable pour ne pas planter sur NULL mais renvoie NULL. Ensuite, vous modifiez la "chaîne", qui n'existe pas. Ceci est un déréférencement de pointeur NULL, à quel point tout va. Sur un système Unix, cela impliquerait la fin immédiate de l'application, avec un segfault. Sous Windows, cela dépend probablement de la marque du système d'exploitation.

+0

Oh, merci beaucoup! Je ne m'en suis pas rendu compte, si cela s'est écrasé, ce serait plus évident. –

Questions connexes