Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/15: Рейтинг темы: голосов - 15, средняя оценка - 4.67
 Аватар для lizard
0 / 0 / 0
Регистрация: 20.09.2011
Сообщений: 14

поиск файлов по строкам

20.09.2011, 14:43. Показов 3184. Ответов 16
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет всем!

Мне нужно решить следующую задачу:
Найти первый файл в каталоге папок, удовлетворяющий заданной маске и содержащий заданный текст. И отобразить его название. Кое-какой код я написал, однако в процессе выполнения вылетает ошибка EAccesVialation.

Ошибка при выполнении 89 строки: fgets(str, 255, file);

Могли бы Вы помочь разобраться в чем ошибка?

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <iostream.h>
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fstream.h>
#include <conio.h>
bool   IsFile(LPCTSTR sPath);
long  GetFindList(LPCTSTR sPath, LPCTSTR sFind, LPCTSTR sText);
bool   IsStrEqualMask(LPCTSTR s, LPCTSTR sFind);
 
 
int main()
{
        char ch;
        char start_dir[MAX_PATH];
        char file_mask[MAX_PATH];
        char text_pattern[255] = { 0 };
 
        do
        {
                 cout<<"Enter directory for search:\r\n";
                 cin>>     start_dir;
 
                        cout<<"Enter mask:\r\n";
                        cin>>file_mask;
                        cout<<"Enter text to find:\r\n";
                        cin>>text_pattern;
                        
                        if(GetFindList(start_dir, file_mask, text_pattern) < 1)
                        cout<<"Files not found\r\n";
 
 
                cout<<"Retry search?\r\nY - yes N - exit\r\n";
                cin>>ch;
        }
        while(ch == 'Y' || ch == 'y');
        return 0;
}
 
 
bool IsFile(LPCTSTR sPath)
{
        bool bFile = false;
        HANDLE hFile = CreateFile
                (
                        sPath, 
                        GENERIC_READ,
                        FILE_SHARE_READ,
                        NULL, 
                        OPEN_EXISTING, 
                        FILE_ATTRIBUTE_NORMAL,
                        NULL
                );
        if(hFile != INVALID_HANDLE_VALUE)
        {
                CloseHandle(hFile);
                bFile = true;
        }
        return bFile;
}
 
 
long GetFindList(LPCTSTR sPath, LPCTSTR sFind, LPCTSTR sText)
{
FILE* file = NULL;
 
       char str[255]={0};
       long nFiles = 0;
        WIN32_FIND_DATA pDATA;
        strcat(strcpy(pDATA.cFileName,sPath),"*.*");
        HANDLE hFile = FindFirstFile(pDATA.cFileName,&pDATA);
        if(hFile != INVALID_HANDLE_VALUE)
        {
                do
                {
                        if(strcmp(pDATA.cFileName,".")  == 0 ||
                           strcmp(pDATA.cFileName,"..") == 0)
                           continue;
                        else
                        {
                                if(pDATA.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY)
                                if(IsStrEqualMask(pDATA.cFileName, sFind))
                                {
 
                                file = fopen("D:\1\1.txt", "r+");
 
 
        fgets(str, 255, file);
 
        if(!strstr(str,sText)){}
        else{
        cout<<"The first file containing this text is:["<<pDATA.cFileName<<"]\r\n";
                             nFiles++;
                             break;     }
                                           }
                                              }
                                                 }
 
                while(FindNextFile(hFile,&pDATA));
        }
        return nFiles;
}
 
bool IsStrEqualMask(LPCTSTR s, LPCTSTR sFind)
{
        bool bEqual = true;
        char delim[] = " \\,.*";
        char * sMask = new char[strlen(sFind) + 1];
        strcpy(sMask,sFind);
        
        char * buf = strtok(sMask,delim);
        while(buf)
        {
                if(!strstr(s,buf))
                {
                        bEqual = false;
                        break;
                }
                buf = strtok(NULL,delim);
        }
        delete [] sMask;
        return bEqual;
}

p.s. поиск в подпапках и проверка файлов, удовлетворяющих маске на содержание заданной фразы, к сожалению пока не реализованы.
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
20.09.2011, 14:43
Ответы с готовыми решениями:

Поиск по строкам
Как в матрице N x M реализовать поиск по строкам (начиная с первой строки) кол-ва чисел, которые не равны нулю?? И если это кол-во равно...

Чтение файлов, запись и дозапись в файл, поиск файлов в каталоге и поиск данных в файле
2. Создать файлы, в которых будут вмещаться строки с именами студентов и их средними балами. Каждый файл будет отвечать отдельной группе. ...

поиск по строкам \n
имеются результат выборки, с такими данными: ММ СМ ДМ КМ Надо проверить, если введенные данные мной в этом списке я делаю так ...

16
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
20.09.2011, 14:51
На самом деле ошибка здесь:
C++
1
file = fopen("D:\1\1.txt", "r+");
символ слэш означает экранирование, видишь даже как еденицы подсвечены. Чтоб ввести символ слеш нужно его экранировать опять таки слешем, т.е. вот так:
C++
1
file = fopen("D:\\1\\1.txt", "r+");
теперь видишь как подсвечено?

Добавлено через 2 минуты
т.е. получается, что файл не открылся, из за этого и ошибка при чтении. Поэтому проверяй файл перед чтением/записью
C++
1
2
3
 file = fopen("D:\\1\\1.txt", "r+");
 if(file)
      fgets(str, 255, file);
0
 Аватар для lizard
0 / 0 / 0
Регистрация: 20.09.2011
Сообщений: 14
20.09.2011, 15:07  [ТС]
Kastaneda
Действительно, спасибо большое за быстрый ответ.

Надо было сразу делать автоматически перебор, а не к конкретному файлу обращаться.


Теперь задача корректно соединить sPath и pDATA.cFileName и применить эту строку в fopen().
Не подскажите как?
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
20.09.2011, 15:16
Цитата Сообщение от lizard Посмотреть сообщение
Теперь задача корректно соединить sPath и pDATA.cFileName и применить эту строку в fopen().
Как я понял нужно к строке, хранящейся в sPath, присоеденить строку из pDATA.FileName. Тогда так
C++
1
strcat(pPath, pDATA.FileName);
при этом размер pPath должен быть достаточным, чтобы вместить pPath+pDATA.FileName. Если нет, то можно завести дополнительный массив для этого:
C++
1
2
3
4
char pPath_and_FileName[512];//размер с запасом
strcpy(pPath_and_FileName, pPath);
strcat(pPath_and_FeliName, pDATA.FileName);
file=fopen(pPath_and_FileName, "r+");
1
 Аватар для lizard
0 / 0 / 0
Регистрация: 20.09.2011
Сообщений: 14
20.09.2011, 15:39  [ТС]
во втором случае показывает следующую ошибку:

[C++ Error] Unit1.cpp(85): E2316 'FileName' is not a member of '_WIN32_FIND_DATAA'
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
20.09.2011, 15:43
это я у тебя не внимательно списал, а ты не проверил
правильно будет pDATA.cFileName
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
20.09.2011, 16:32
Цитата Сообщение от lizard Посмотреть сообщение
Могли бы Вы помочь разобраться в чем ошибка?
- у меня спросить
Поиск файла по шаблону

Цитата Сообщение от lizard Посмотреть сообщение
file = fopen("D:\1\1.txt", "r+");
fgets(str, 255, file);
- накой было код переводить
Список полей WIN32_FIND_DATA
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
typedef struct _WIN32_FIND_DATAA {
    DWORD dwFileAttributes;
    FILETIME ftCreationTime;
    FILETIME ftLastAccessTime;
    FILETIME ftLastWriteTime;
    DWORD nFileSizeHigh;
    DWORD nFileSizeLow;
    DWORD dwReserved0;
    DWORD dwReserved1;
    CHAR   cFileName[ MAX_PATH ];
    CHAR   cAlternateFileName[ 14 ];
#ifdef _MAC
    DWORD dwFileType;
    DWORD dwCreatorType;
    WORD  wFinderFlags;
#endif
} WIN32_FIND_DATAA, *PWIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
Добавлено через 5 минут
lizard, есть цикл поиска, нужен первый файл удовлетворяющий маске так введи break и strcmp код топика ужастен
0
 Аватар для lizard
0 / 0 / 0
Регистрация: 20.09.2011
Сообщений: 14
20.09.2011, 16:41  [ТС]
да уж. тупанул я)

если все до конца исправить, применительно к коду в перовом посте, то вот так будет

C++
1
2
3
4
char sPath_and_FileName[512];
strcpy(sPath_and_FileName, sPath);
strcat(sPath_and_FileName, pDATA.cFileName);
file=fopen(sPath_and_FileName, "r+");


спасибо еще раз (:

Добавлено через 6 минут
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
есть цикл поиска, нужен первый файл удовлетворяющий маске так введи break
так он и был. строка 95.

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
strcmp код топика ужастен
можно подробнее объяснить?
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
20.09.2011, 16:47
lizard, сейчас перепишу, верней восстановлю код + введу рекурсию чтобы все подкаталоги обрабатывал
Цитата Сообщение от lizard Посмотреть сообщение
можно подробнее объяснить?
Цитата Сообщение от lizard Посмотреть сообщение
GetFindList
- это уже готовая функция поиска, какой ещё константный путь в ней пробивать???
Цитата Сообщение от Kastaneda Посмотреть сообщение
file = fopen("D:\\1\\1.txt", "r+");
Ты файл ишещь или открываешь уже наперёд известный?

Добавлено через 1 минуту
Вобщем реализовываю задание - вбиваем каталог и выполняем в нём поиск первого файла удовлетворяющего маске, скоро отпишусь...(как я ShlDialog выбора каталога напугал и будем его руками вводить)
0
 Аватар для lizard
0 / 0 / 0
Регистрация: 20.09.2011
Сообщений: 14
20.09.2011, 16:56  [ТС]
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Ты файл ишещь или открываешь уже наперёд известный?
да ясное дело что ищем. Я просто отладку делал с реакцией на найденное слово в файле, поэтому ввел адрес на время
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
20.09.2011, 17:24
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Вобщем реализовываю задание - вбиваем каталог и выполняем в нём поиск первого файла удовлетворяющего маске
Вот Си код (SHL-диалог выбора файла не убирал, т.к достаёт вручную вбивать пути на своём компьютере, если есть желание его убрать - убираем, у меня этого желания нет)
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#include <iostream.h>//i/o
#include <windows.h> //FindFirst(Next)File
#include <shlobj.h>  //Диалог выбора файла
#include <stdio.h>   //sprintf
//Руссификация
ostream& operator<<(ostream &stream,char* s){
    for(char* ps=s; *ps; ps++){
        if(*ps=='ё')
            stream<<char(241);
        else if(*ps=='Ё')
            stream<<char(240);
        else if(*ps>=-64 && *ps<=-17)           
            stream<<char(*ps+64+128);
        else if(*ps<0)
            stream<<char(*ps+64+176);
        else
            stream<<*ps;
    }
    return stream;
}
 
char * SelectFile(HWND hWnd);
bool   IsFile(LPCTSTR sPath);
bool   FindFile(LPCTSTR sPath, LPCTSTR sFind);
bool   IsStrEqualMask(LPCTSTR s, LPCTSTR sFind);
 
int main()
{
    char ch;
    char szFilePath[MAX_PATH];
    char szFindMask[MAX_PATH];
    HWND hWnd = GetForegroundWindow();//Находим дескриптор окна консоли
    do
    {
        if(!strcpy(szFilePath,SelectFile(hWnd)))
            cout<<"Файл не выбран";
        else
        {
            if(IsFile(szFilePath))
            {
                    cout<<"Выбран файл\r\n";
                    szFilePath[strlen(szFilePath) - strlen(strrchr(szFilePath,'\\')) + 1] = '\0'; 
            }
            cout<<"Каталог для поиска:\r\n["<<szFilePath<<"]\r\n";
            cout<<"Введите маску поиска\r\n";
            cin>>szFindMask;
            if(!FindFile(szFilePath, szFindMask))
                cout<<"Поиск не дал результатов\r\n";
        }
        cout<<"Y - Повторить поиск\r\n";
        cin>>ch;
    }
    while(ch == 'Y' || ch == 'y');
    return 0;
}
 
char * SelectFile(HWND hWnd)
{
    ShowWindow(hWnd,SW_HIDE);
    char sPath[MAX_PATH];sPath[0] = '\0';
    LPCITEMIDLIST lpItemDList;
    BROWSEINFO bi = {NULL, NULL, sPath,
       "Выберите файл или каталог",
        BIF_DONTGOBELOWDOMAIN|BIF_BROWSEINCLUDEFILES,
        NULL,
        NULL,
        0
    };
    if((lpItemDList = SHBrowseForFolder(&bi)))
    {
        if(SHGetPathFromIDList(lpItemDList, sPath))
            GetShortPathName((LPCTSTR)sPath,sPath,strlen(sPath));
    }
    ShowWindow(hWnd,SW_SHOW);
    return &sPath[0];
}
 
bool IsFile(LPCTSTR sPath)
{
    bool bFile = false;
    HANDLE hFile = CreateFile
        (
            sPath, 
            GENERIC_READ,
            FILE_SHARE_READ,
            NULL, 
            OPEN_EXISTING, 
            FILE_ATTRIBUTE_NORMAL,
            NULL
        );
    if(hFile != INVALID_HANDLE_VALUE)
    {
        CloseHandle(hFile);
        bFile = true;
    }       
    return bFile;
}
 
 
bool FindFile(LPCTSTR sPath, LPCTSTR sFind)
{
    bool bFind = false;
    char sDir[MAX_PATH];
    WIN32_FIND_DATA pDATA;
    strcat(strcpy(pDATA.cFileName,sPath),"\\*.*");
    HANDLE hFile = FindFirstFile(pDATA.cFileName,&pDATA);
    if(hFile != INVALID_HANDLE_VALUE)
    {
        do
        {
            if(strcmp(pDATA.cFileName,".")  == 0 ||
               strcmp(pDATA.cFileName,"..") == 0)
               continue;
            else
            {
                if(pDATA.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY)
                if(IsStrEqualMask(pDATA.cFileName, sFind))
                {
                    cout<<"Найден файл :["<<pDATA.cFileName<<"]\r\n";
                    bFind = true;
                    break;
                }
                else
                {
                    //Нашли подкаталог - ныряем в него
                    sprintf(sDir,"%s\\%s",sPath, pDATA.cFileName);
                    if((bFind = FindFile(sDir, sFind)))
                        break;//Если поиск успешен, сразу прекращаем поиск
                }
            }
        }
        while(FindNextFile(hFile,&pDATA));
    }
    return bFind;
}
 
bool IsStrEqualMask(LPCTSTR s, LPCTSTR sFind)
{
    bool bEqual = true;
    //шаблон может содержать ' ' '\\' ',' '.' '*'
    char delim[] = " \\,.*";
    char * sMask = new char[strlen(sFind) + 1];
    strcpy(sMask,sFind);
    
    char * buf = strtok(sMask,delim);
    while(buf)
    {
        if(!strstr(s,buf))
        {
            bEqual = false;
            break;
        }
        buf = strtok(NULL,delim);
    }
    delete [] sMask;
    return bEqual;
}
[Результат работы]
Каталог для поиска:
[D:\МОИДОК~1\0292~1\21EF~1]
Введите маску поиска
*.xls
Найден файл :[Общий баланс(сентябрь)-2011.xls]
Y - Повторить поиск


Добавлено через 1 минуту
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
if(IsStrEqualMask(pDATA.cFileName, sFind))
* * * * * * * * * * * * * * * * {
* * * * * * * * * * * * * * * * * * * * cout<<"Найден файл :["<<pDATA.cFileName<<"]\r\n";
* * * * * * * * * * * * * * * * * * * * bFind = true;
* * * * * * * * * * * * * * * * * * * * break;
* * * * * * * * * * * * * * * * }
* * * * * * * * * * * * * * * * else
* * * * * * * * * * * * * * * * {
* * * * * * * * * * * * * * * * * * * * //Нашли подкаталог - ныряем в него
* * * * * * * * * * * * * * * * * * * * sprintf(sDir,"%s\\%s",sPath, pDATA.cFileName);
* * * * * * * * * * * * * * * * * * * * if((bFind = FindFile(sDir, sFind)))
* * * * * * * * * * * * * * * * * * * * * * * * break;//Если поиск успешен, сразу прекращаем поиск
* * * * * * * * * * * * * * * * }
if((bFind = FindFile(sDir, sFind))) - рекурсивный обход всех подкаталогов

Добавлено через 10 минут
Вот код аналогичной функциональности позволяющий исключить ShlDialog
C
1
2
3
4
5
6
7
8
9
szFilePath[0] = '\0';
        cout<<"Введите каталог\r\n";
        cin.getline(szFilePath,MAX_PATH);
        if(szFilePath[0] == '\0')
            cout<<"Файл не выбран\r\n";
        else
        {
            if(IsFile(szFilePath))
            {
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
20.09.2011, 17:30
lizard, если пишешь на С++, то логичней вместо char* использовать для строк класс string
0
 Аватар для lizard
0 / 0 / 0
Регистрация: 20.09.2011
Сообщений: 14
20.09.2011, 17:31  [ТС]
за рекурсию спасибо.
Но в задании цель не вывести название первого файла удовлетворяющего маске, а вывести название первого файла удовлетворяющего маске и в содержащего заданную слово\фразу. Поэтому и входящий параметр добавился в функцию. И поэтому же там появились строки

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
...
 
char sPath_and_FileName[512];
strcpy(sPath_and_FileName, sPath);
strcat(sPath_and_FileName, pDATA.cFileName);
file=fopen(sPath_and_FileName, "r+");
fgets(str, 255, file);
 
        if(!strstr(str,sText)){}
        else{
        cout<<"The first file containing this text is:["<<pDATA.cFileName<<"]\r\n";
                             nFiles++;
                             break;     }
...
0
Эксперт С++
 Аватар для Nameless One
5828 / 3479 / 358
Регистрация: 08.02.2010
Сообщений: 7,448
20.09.2011, 17:35
Кстати, по теме, глянь исходники find
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
20.09.2011, 18:32
Цитата Сообщение от lizard Посмотреть сообщение
file=fopen(sPath_and_FileName, "r+");
fgets(str, 255, file);
if(!strstr(str,sText)){}
* * * * else{
- в функцию нужно передавать текст для поиска, а не открывать файл, сейчас подправлю, если честно задание сложно было понять...
0
 Аватар для lizard
0 / 0 / 0
Регистрация: 20.09.2011
Сообщений: 14
20.09.2011, 18:53  [ТС]
Так текст нужно и передавать (что уже реализовано) и считывать из файлов - что бы найти искомое в них. Ну это насколько я понимаю алгоритм.


Может быть просто я не оч понятно описал.

1) функция(директория поиска, маска, искомый текст)

выводит на экран первый подходящий файл.


по большому счету в этой теме уже есть весь необходимый код, надо только соединить все в 1 программу
0
Автор FAQ
 Аватар для -=ЮрА=-
6614 / 4256 / 401
Регистрация: 08.08.2009
Сообщений: 10,325
Записей в блоге: 24
20.09.2011, 19:10
Вот подправил
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#include <iostream.h>//i/o
#include <windows.h> //FindFirst(Next)File
#include <shlobj.h>  //Диалог выбора файла
#include <stdio.h>   //sprintf
//Руссификация
ostream& operator<<(ostream &stream,char* s){
        for(char* ps=s; *ps; ps++){
                if(*ps=='ё')
                        stream<<char(241);
                else if(*ps=='Ё')
                        stream<<char(240);
                else if(*ps>=-64 && *ps<=-17)                   
                        stream<<char(*ps+64+128);
                else if(*ps<0)
                        stream<<char(*ps+64+176);
                else
                        stream<<*ps;
        }
        return stream;
}
 
char * SelectFile(HWND hWnd);
bool   IsFile(LPCTSTR sPath);
//Поиск файла в каталоге sPath по маске sMask и наличии текста sFind в нём
bool   FindFile(LPCTSTR sPath, LPCTSTR sMask, LPCTSTR sFind);
//Поиск текста sFind в файле sPath
bool   FindText(LPCTSTR sPath, LPCTSTR sFind);
bool   IsStrEqualMask(LPCTSTR s, LPCTSTR sFind);
 
int main()
{
    char ch;
    char szFilePath[MAX_PATH];
    char szFindMask[MAX_PATH];
    char szFindText[1024];//Для вводе текста для поиска есть хоть каки*то ограничения
    HWND hWnd = GetForegroundWindow();//Находим дескриптор окна консоли
    do
    {
        if(!strcpy(szFilePath,SelectFile(hWnd)))
            cout<<"Файл не выбран\r\n";
        else
        {
            if(IsFile(szFilePath))
            {
                cout<<"Выбран файл\r\n";
                szFilePath[strlen(szFilePath) - strlen(strrchr(szFilePath,'\\')) + 1] = '\0'; 
            }
            cout<<"Каталог для поиска:\r\n["<<szFilePath<<"]\r\n";
            cout<<"Введите маску поиска\r\n";
            cin.getline(szFindMask,MAX_PATH);
            cout<<"Введите текст поиска\r\n";
            cin.getline(szFindText,1024);
            if(!FindFile(szFilePath, szFindMask, szFindText))
                cout<<"Поиск не дал результатов\r\n";
        }
        cout<<"Y - Повторить поиск\r\n";
        cin>>ch;
    }
    while(ch == 'Y' || ch == 'y');
    return 0;
}
 
char * SelectFile(HWND hWnd)
{
    ShowWindow(hWnd,SW_HIDE);
    char sPath[MAX_PATH];sPath[0] = '\0';
    LPCITEMIDLIST lpItemDList;
    BROWSEINFO bi = 
    {
        NULL, 
        NULL, 
        sPath,
        "Выберите файл или каталог",
        BIF_DONTGOBELOWDOMAIN|BIF_BROWSEINCLUDEFILES,
        NULL,
        NULL,
        0
    };
    if((lpItemDList = SHBrowseForFolder(&bi)))
    {
        if(SHGetPathFromIDList(lpItemDList, sPath))
            GetShortPathName((LPCTSTR)sPath,sPath,strlen(sPath));
    }
    ShowWindow(hWnd,SW_SHOW);
    return &sPath[0];
}
 
bool IsFile(LPCTSTR sPath)
{
    bool bFile = false;
    HANDLE hFile = CreateFile
        (
            sPath, 
            GENERIC_READ,
            FILE_SHARE_READ,
            NULL, 
            OPEN_EXISTING, 
            FILE_ATTRIBUTE_NORMAL,
            NULL
        );
     if(hFile != INVALID_HANDLE_VALUE)
     {
         CloseHandle(hFile);
         bFile = true;
     }               
     return bFile;
}
 
 
bool FindFile(LPCTSTR sPath, LPCTSTR sMask, LPCTSTR sFind)
{
    bool bFind = false;
    char sDir[MAX_PATH];
    WIN32_FIND_DATA pDATA;
    strcat(strcpy(pDATA.cFileName,sPath),"\\*.*");
    HANDLE hFile = FindFirstFile(pDATA.cFileName,&pDATA);
    if(hFile != INVALID_HANDLE_VALUE)
    {
        do
        {
            if(strcmp(pDATA.cFileName,".")  == 0 ||
               strcmp(pDATA.cFileName,"..") == 0)
               continue;
            else
            {
                sprintf(sDir,"%s\\%s",sPath, pDATA.cFileName);
                if(pDATA.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY)
                {
                    if(IsStrEqualMask(pDATA.cFileName, sMask))
                    if(FindText(sDir, sFind))
                    {
                        cout<<"Найден файл :["<<sDir<<"]\r\n";
                        bFind = true;
                        //break;//Если поиск успешен, сразу прекращаем поиск
                    }
                }
                else
                {
                    //Нашли подкаталог - ныряем в него
                    if((bFind = FindFile(sDir, sMask, sFind)))
                    {
                        //break;//Если поиск успешен, сразу прекращаем поиск
                    }
                }
            }
        }
        while(FindNextFile(hFile,&pDATA));
    }
    return bFind;
}
 
bool FindText(LPCTSTR sPath, LPCTSTR sFind)
{
    long sLen;
    char * str;
    bool bRet = false;
    FILE * f = fopen(sPath,"r");
    if(f)
    {
        fseek(f,0,SEEK_END);
        sLen = ftell(f);
        fseek(f,0,SEEK_SET);
        if((str = new char[sLen + 1]))
        {
            fread(str,sLen,1,f);
            str[sLen] = '\0';
        }
        fclose(f);
        if(str)
        {
            //Решил не изобретать велосипед а воспользуваться уже имеющейся функцией
            bRet = IsStrEqualMask(str, sFind);
            delete [] str;
        }
    }
    return bRet;
}
 
bool IsStrEqualMask(LPCTSTR s, LPCTSTR sFind)
{
    bool bEqual = true;
    //шаблон может содержать ' ' '\\' ',' '.' '*'
    char delim[] = " \\,.*";
    char * sMask = new char[strlen(sFind) + 1];
    strcpy(sMask,sFind);
        
    char * buf = strtok(sMask,delim);
    while(buf)
    {
        if(!strstr(s,buf))
        {
            bEqual = false;
            break;
        }
        buf = strtok(NULL,delim);
     }
     delete [] sMask;
     return bEqual;
}
Проверял работу на файле который прикладываю (скопировал в 2 подкаталога). Поиск длиться какое то премя, но всё отработало норм
[Результат работы]
Каталог для поиска:
[D:\MICROS~1]
Введите маску поиска
~Test*.txt
Введите текст поиска
TEST
Найден файл :[D:\MICROS~1\CyberForum\SearchMaskText\~T estFile~.txt]
Найден файл :[D:\MICROS~1\CyberForum\~TestFile~.txt]
Поиск не дал результатов
Y - Повторить поиск

PS:Чтобы убить Program idle (потря программой фокуса на окно, можно ввести функцию которую привожу ниже), вставляем её в цикл

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
void PumpMessages(HWND hWnd)
{
    ASSERT(hWnd!=NULL);
    MSG msg;
    // Handle dialog messages
    while(PeekMessage(&msg, hWnd, 0, 0, PM_REMOVE))
    {
        if(!IsDialogMessage(hWnd,&msg))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);  
        }
    }
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
20.09.2011, 19:10
Помогаю со студенческими работами здесь

Как сделать чтение файлов по строкам?
Пишу программу где нужно брать некоторые данные с текста(txt) которые будут написаны построчно, нужно сделать обращение к строке (взять...

Поиск по двум строкам
Вообщем надо осуществить поиск по двум полям из БД, помоги исправить код, видимо что-то с кавычками: Filter:= ('PASS_NUM ='+...

Поиск и запись по строкам
Всем привет, нужен батник. Который будет делать поиск кавычек в файле. И выводить в какой строке сколько кавычек. Вот так: Строка 1...

Поиск по строкам в StringGrid
Помогите пожалуйста сделать программу, не сделать поиск по строкам Дан текстовый файл. Структура строки текстового файла: фамилия и...

Поиск по строкам файла
Есть текстовый файл, который отображается в Memo1 и компоненты Edit1 и edit2 Нужно, чтобы выполнялся поиск по строкам,...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru