- 论坛徽章:
- 2
|
发个windows文件通配例子。- #include <ctype.h>
- #include <stdio.h>
- #include <windows.h>
- #define PATH_SPLITTER '\\'
- #define LENGTH(a) (sizeof(a)/sizeof((a)[0]))
- struct file_node
- {
- long size;
- };
- int nstr_chr(const char *s, int off, int lmt, int c)
- {
- for (; off < lmt; ++off) {
- if (s[off] == c) {
- return off;
- }
- }
- return -1;
- }
- int nstr_rchr(const char *s, int off, int lmt, int c)
- {
- for (; off < lmt; --lmt) {
- if (s[lmt - 1] == c) {
- return lmt;
- }
- }
- return -1;
- }
- int nstr_npbrk(const char *s, int off, int lmt, const char *charset, int charset_len)
- {
- for (; off < lmt; ++off) {
- if (nstr_chr(charset, 0, charset_len, s[off]) != -1) {
- return off;
- }
- }
- return -1;
- }
- int nstr_lmt(const char *s, int lmt)
- {
- int off;
- off = nstr_chr(s, 0, lmt, '\0');
- if (off == -1) {
- off = lmt;
- }
- return off;
- }
- int nstr_nmatch(const char *s, int off, int lmt, const char *rules, int rules_len)
- {
- int rules_off;
- int rules_lmt;
- int rules_next;
- for (rules_off = 0; rules_off < rules_len; rules_off = rules_next) {
- rules_lmt = nstr_npbrk(rules, rules_off, rules_len, "*?", 2);
- if (rules_lmt == -1) {
- rules_next = rules_len;
- rules_lmt = rules_len;
- }else {
- rules_next = rules_lmt + 1;
- }
- if (rules_off < rules_lmt) {
- if (off + rules_lmt - rules_off <= lmt) {
- if (strncmp(s + off, rules + rules_off, rules_lmt - rules_off) == 0) {
- off += rules_lmt - rules_off;
- }else {
- return 0;
- }
- }else {
- return 0;
- }
- }
- if (rules_lmt < rules_len) {
- if (rules[rules_lmt] == '?') {
- if (off + 1 <= lmt) {
- ++off;
- }else {
- return 0;
- }
- }else { /* '*' */
- for(; off < lmt; ++off) {
- if (nstr_nmatch(s, off, lmt, rules + rules_next, rules_len - rules_next)) {
- return 1;
- }
- }
- return off == lmt && rules_next == rules_len;
- }
- }
- }
- return off == lmt ? 1 : 0;
- }
- int nstr_nmatch_more(const char *s, int off, int lmt, const char *rules, int rules_len)
- {
- int rules_off;
- int rules_lmt;
- int rules_next;
- for (rules_off = 0; rules_off < rules_len; rules_off = rules_next) {
- rules_lmt = nstr_chr(rules, rules_off, rules_len, ';');
- if (rules_lmt == -1) {
- rules_lmt = rules_len;
- rules_next = rules_len;
- }else {
- rules_next = rules_lmt + 1;
- }
- if (rules_off < rules_lmt) {
- if (nstr_nmatch(s, off, lmt, rules + rules_off, rules_lmt - rules_off)) {
- return 1;
- }
- }
- }
- return 0;
- }
- int get_path_directory_off(const char *s, int off)
- {
- if (off >= 0) {
- if (off >= 2 && s[off - 1] == ':' && isalpha(s[off - 2])) {
- return 2;
- }
- return 0;
- }
- return -1;
- }
- int get_path_filename_off(const char *s, int off)
- {
- int dir_off;
- int name_off;
- if (off >= 0) {
- dir_off = get_path_directory_off(s, off);
- name_off = nstr_rchr(s, dir_off, off, PATH_SPLITTER);
- if (name_off == -1) {
- name_off = dir_off;
- }
- return name_off;
- }
- return -1;
- }
- /* enum_dir
- *
- * RETURN
- *
- * 0; SUCCESS
- * -1; ERROR: buffer overflow
- * -2; ERROR: directory not found
- * -3; ERROR: file too large
- * -4; ERROR: invalid call back function
- * #; ERROR: enum_func defined error
- */
- int enum_dir(char *s, int off, int lmt, struct file_node *node, int skip_error, int (*enum_func)(char *s, int off, int lmt, void *data), void *data)
- {
- WIN32_FIND_DATA find_data;
- HANDLE hFind;
- int retval;
- int name_off;
- int name_len;
- retval = 0;
- if (off >= 0 && off < lmt) {
- name_off = get_path_filename_off(s, off);
- }else {
- retval = -1; /* ERROR: buffer overflow */
- }
- if (retval == 0) {
- if (name_off == off) {
- if (name_off + 3 <= lmt) {
- strncpy(s + name_off, "*.*", 3);
- off = name_off + 3;
- }else {
- retval = -1; /* ERROR: buffer overflow */
- }
- }
- }
- if (retval == 0) {
- if (off + 1 <= lmt) {
- s[off] = '\0';
- }else {
- retval = -1; /* ERROR: buffer overflow */
- }
- }
- if (retval == 0) {
- hFind = FindFirstFile(s, &find_data);
- if (hFind != INVALID_HANDLE_VALUE) {
- do {
- if (strcmp(find_data.cFileName, ".") != 0 && strcmp(find_data.cFileName, "..") != 0) {
- name_len = nstr_lmt(find_data.cFileName, LENGTH(find_data.cFileName));
- if (name_off + name_len <= lmt) {
- strncpy(s + name_off, find_data.cFileName, name_len);
- off = name_off + name_len;
- }else {
- retval = -1; /* ERROR: buffer overflow */
- }
- if (retval == 0) {
- if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
- if (off + 1 <= lmt) {
- s[off] = PATH_SPLITTER;
- ++off;
- }else {
- retval = -1; /* ERROR: buffer overflow */
- }
- }
- }
- if (retval == 0) {
- if (off + 1 <= lmt) {
- s[off] = '\0';
- }else {
- retval = -1; /* ERROR: buffer overflow */
- }
- }
- if (retval == 0) {
- if (find_data.nFileSizeHigh == 0) {
- node->size = find_data.nFileSizeLow;
- }else {
- retval = -3; /* ERROR: file size too large */
- }
- }
- if (retval == 0) {
- if (enum_func != NULL) {
- retval = (*enum_func)(s, off, lmt, data);
- }else {
- retval = -4; /* ERROR: invalid call back function */
- }
- }
- if (skip_error) {
- retval = 0;
- }
- }
- }while (retval == 0 && FindNextFile(hFind, &find_data));
- FindClose(hFind);
- }else {
- retval = -2; /* ERROR: directory not found */
- }
- }
- return retval;
- }
- struct find_param
- {
- char filter[256];
- int filter_len;
- struct file_node node;
- int total_find;
- int skip_error;
- };
- int find_func(char *s, int off, int lmt, struct find_param *param)
- {
- int name_off;
- name_off = get_path_filename_off(s, off);
- if (name_off == off) {
- return enum_dir(s, off, lmt, ¶m->node, param->skip_error, find_func, param);
- }else {
- if (nstr_nmatch_more(s, name_off, off, param->filter, param->filter_len)) {
- printf("%s %d\n", s, param->node.size);
- ++param->total_find;
- }
- return 0;
- }
- }
- int main(void)
- {
- char buf[512];
- struct find_param param;
- int retval;
- strcpy(buf, "c:\\");
- strcpy(param.filter, "read*.txt;*.exe");
- param.filter_len = 15;
- param.total_find = 0;
- param.skip_error = 1;
- retval = enum_dir(buf, 3, 512, ¶m.node, param.skip_error, find_func, ¶m);
- printf("TOTAL FIND %d file(s)\n", param.total_find);
- if (retval) {
- printf("ERROR %d\n", retval);
- }
- return retval;
- }
复制代码 |
|