2010-03-30 20 views
1

我想为Windows编写一个小助手,它最终将接受文件扩展名作为参数,并返回当前目录中那种文件的数量。为什么触摸“d_name”调用readdir()失败?

为此,我正在读取目录中的文件条目,并在获取扩展名后,我想将其转换为小写字母以将其与尚未添加的指定参数进行比较。

将扩展名转换为小写时,我发现即使是重复的字符串变量d_name也会导致一个奇怪的行为,就像不再调用readdir调用。

这里是我现在使用(注释的代码是初步),并输出针对给定目录中的代码:

#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"); 
} 

输出,而无需修改重复(改性和第二printf呼叫注释):同一个目录的

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 

输出(与上面的代码中,用2个printf S):

Strings: (null) (null) 

有什么问题吗?这是一个编译器问题吗?我现在在Windows(MinGW)中使用GCC 4.4.3。

非常感谢您的帮助。

顺便说一下,有没有其他的方式来使用不使用POSIX功能的Windows环境中的文件和目录?

回答

2

在Windows系统上,“native”API不是POSIX,而是Win32。使用Win32,请尝试使用FindFirstFile()FindNextFile()

至于你的代码:你的第一行显示test()的第一个调用带有一个空指针(这就是你的strrch()函数返回的文件名为".")。 strdup()非常友善,不会在NULL上崩溃,但会返回NULL。然后修改不存在的“字符串”。这是一个NULL指针解引用,在这一点上什么都有。在Unix系统上,这意味着立即终止应用程序,并出现段错误。在Windows上,这可能取决于OS品牌。

+0

哦,非常感谢!我没有意识到,如果它坠毁,反而会更明显。 – 2010-03-30 12:32:14