Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Поиск текста в файлах (http://forum.oszone.net/showthread.php?t=147764)

student_po 12-08-2009 11:46 1191780

Поиск текста в файлах
 
Доброго времени суток. В институте дали задания написать программу, которая должна искать текст в файлах (типа поиска в Windows). Но искать надо несколько строк сразу, в форматах doc, rtf, txt, и все это в графическом режиме.
Помогите с созданием GUI. Просто в C++ новичок. Написать cpp это ладно, а здесь ничего не получается.

Вот набросок (поиска файлов).

Код:

#include <iostream.h>
#include <windows.h>
#include<fstream.h>
#include<string.h>
#include<stdio.h>
#define rz 100
main()
{
        char path[MAX_PATH],mask[MAX_PATH],ch,line [rz],stxt[MAX_PATH],files[MAX_PATH];
        cout<<"Search dir:";
        cin.getline(path,260,'\n');
        cout<<"Search mask:";
        cin.getline(mask,260,'\n');
        cout<<"Search:";
        cin.getline(stxt,260,'\n');
//Sf
        WIN32_FIND_DATA file;
        HANDLE hfile;
        char fpath[MAX_PATH];
        strcpy(fpath,path);
        strcat(fpath,"\\");
        SetCurrentDirectory(fpath);
        strcat(fpath,mask);
        hfile=FindFirstFile(fpath,&file);       
        if(hfile!=INVALID_HANDLE_VALUE)
        {
                do
                {
//St               
                        strcpy(files,file.cFileName);
                        fstream fo;
                        fo.open (file.cFileName,ios::in);
                        while(fo.get(ch))
                        {
                                fo.get(line,rz);
                                if ((strstr(line,stxt))!=NULL)
                                {
                                //        cout<<line<<'\n';
                                        strcpy(files,file.cFileName);
//                                        cout<<file.cFileName<<'\n';
                                        cout<<files<<'\n';
                                        break;
                                }
                        }
                        cout<<'\n';
                        fo.close();
                }
                while(FindNextFile(hfile,&file)!=0);
                FindClose(hfile);
        }
//end Sf       
        return 0;
}
//До кондиции довести напильником!!!

Может у кого есть поправки. Или сама программа. Заранее спасибо всем.

P.S. Хочется на Visual C++ 6 и выше до 9. Но если нет, то и на других языках пойдет.

Admiral 12-08-2009 23:42 1192322

Доброго времени суток student_po, не совсем понятно, какого масштаба задание: практика, лаба, расчётно-графическая, другое?
Меня смущает в перечисленных форматах наличие doc и rtf, так как для последних встроенных возможностей языка будет не достаточно. Придётся писать довольно массивный код, дабы получить возможность без проблемного чтения данных файлов (по сути свой Word/WordPad), чего не скажешь про txt.
В технологии поиска можно предусмотреть использование ключевых слов "и" "или" и т.д. или без таких, опираясь на спец символы, вводящие в окно поиска, дабы искать по несколько строк сразу.

Для построения GUI в предполагаемых средствах программирования Visual C++ 6 и выше до 9 во всех этих версия можно построить, используя или чистый Win32 Api, или библиотеку классов MFC.
В версиях 7.Х и выше возможно так же использовать и WinForms (который использует .Net Framework), а начиная с 8й версии и выше можно и Windows Presentation Foundation (тоже использует .Net Framework).
Если окно нужно строить используя WIN32 API, то вот
прототип окна поиска
Код:

#include <windows.h>
#include <commctrl.h>

#pragma comment(lib, "comctl32.lib")

enum {ID_BUTTON};

HWND hWndListView;

LRESULT CALLBACK WindowFunc(HWND hWnd,UINT message,
                        WPARAM wParam,LPARAM lParam)
{
        switch (message)
        {       
                case WM_CREATE:
                        CreateWindow(
                                TEXT("STATIC"),
                                TEXT("Search by any or all of the criterial below."),
                                WS_CHILD | WS_VISIBLE,
                                10,
                                10,
                                270,
                                20,
                                hWnd,
                                NULL,
                                NULL,
                                NULL);
                        CreateWindow(
                                TEXT("STATIC"),
                                TEXT("All or part of the file name:"),
                                WS_CHILD | WS_VISIBLE,
                                10,
                                45,
                                250,
                                20,
                                hWnd,
                                NULL,
                                NULL,
                                NULL);
                        CreateWindow(
                                TEXT("EDIT"),
                                NULL,
                                WS_CHILD | WS_VISIBLE | ES_LEFT | ES_MULTILINE ,
                                10,
                                65,
                                270,
                                20,
                                hWnd,
                                NULL,
                                NULL,
                                NULL);
                        CreateWindow(
                                TEXT("STATIC"),
                                TEXT("A word or phase in the file:"),
                                WS_CHILD | WS_VISIBLE,
                                10,
                                85,
                                250,
                                20,
                                hWnd,
                                NULL,
                                NULL,
                                NULL);
                        CreateWindow(
                                TEXT("EDIT"),
                                NULL,
                                WS_CHILD | WS_VISIBLE | ES_LEFT | ES_MULTILINE ,
                                10,
                                105,
                                270,
                                20,
                                hWnd,
                                NULL,
                                NULL,
                                NULL);
                        CreateWindow(
                                TEXT("STATIC"),
                                TEXT("Look in:"),
                                WS_CHILD | WS_VISIBLE,
                                10,
                                125,
                                100,
                                20,
                                hWnd,
                                NULL,
                                NULL,
                                NULL);
                        CreateWindow(
                                TEXT("EDIT"),
                                NULL,
                                WS_CHILD | WS_VISIBLE | ES_LEFT | ES_MULTILINE ,
                                10,
                                145,
                                270,
                                20,
                                hWnd,
                                NULL,
                                NULL,
                                NULL);
                        CreateWindow(
                                TEXT("BUTTON"),
                                TEXT("Search"),
                                BS_PUSHBUTTON | WS_VISIBLE | WS_CHILD | WS_TABSTOP,
                                200,
                                200,
                                80,
                                30,
                                hWnd,
                                NULL,       
                                NULL,
                                NULL);
                break;

                case WM_COMMAND:
                        switch(wParam)
                        {
                                case ID_BUTTON:
                                        //MessageBox(NULL, TEXT("Search Results"), TEXT("About"), MB_ICONASTERISK | MB_OK);
                                ShowWindow(hWndListView,SW_SHOW);
                                break;
                        }
                        break;

        case WM_DESTROY:
                        PostQuitMessage (0);
                break;

        default:
                        return DefWindowProc (hWnd,message,wParam,lParam);
        }
                return 0;
}

int WINAPI WinMain (HINSTANCE hThisInst,HINSTANCE hPrevInst,
                                LPSTR lpszArgs,int nWinMode)
{       
        WNDCLASS wcl;
        wcl.style = 0;
        wcl.lpfnWndProc = WindowFunc;
        wcl.cbClsExtra = 0;
        wcl.cbWndExtra = 0;
        wcl.hInstance = hThisInst;
        wcl.hIcon = LoadIcon (NULL, IDI_APPLICATION);
        wcl.hCursor = LoadCursor (NULL, IDC_ARROW);
        wcl.hbrBackground = (HBRUSH)COLOR_WINDOW;
        wcl.lpszMenuName = NULL;
        wcl.lpszClassName = TEXT("Search");

        if (!RegisterClass (&wcl))
                return -1;
        HWND hWnd = CreateWindowEx (WS_EX_TOPMOST,
                wcl.lpszClassName,
                TEXT("Search Results"),
                WS_TILEDWINDOW,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                CW_USEDEFAULT,
                HWND_DESKTOP,
                NULL,
                hThisInst,
                NULL);
        if (!hWnd)
                return -1;

        ShowWindow (hWnd,nWinMode);
        UpdateWindow (hWnd);
        MSG msg;

hWndListView = CreateWindow(
                                WC_LISTVIEW,
 NULL,
                                WS_CHILD | LVS_REPORT | LVS_EDITLABELS,
        300,
        10,
        250,
        220,
        hWnd,
        NULL,
        NULL,
        NULL);
#ifdef UNICODE
        TCHAR szColumnHeader[3][12] = {TEXT("Name"), TEXT("In Folder"), TEXT("Size")};
#else
        char szColumnHeader[3][12] = {TEXT("Name"), TEXT("In Folder"), TEXT("Size")};
#endif
        int index;
        int iiWidth[3];
        LV_COLUMN lvC;

        ListView_SetExtendedListViewStyle(hWndListView, LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES);

        iiWidth[0] = 60;
        iiWidth[1] = 100;
        iiWidth[2] = 400;

        lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
        lvC.fmt = LVCFMT_LEFT;

        for(index = 0; index < 3; index++)
{
                lvC.iSubItem = index;
                lvC.cx = iiWidth[index];
                lvC.pszText = szColumnHeader[index];
                ListView_InsertColumn(hWndListView,index,&lvC);
        }

        while(GetMessage(&msg, NULL, 0, 0) > 0)
        {
                TranslateMessage (&msg);
                DispatchMessage (&msg);
        }
        return msg.wParam;
}

По нажатию на кнопку Поиск ("Search") появляется окно с предполагаемым результатом. Кроме того в коде не совсем корректно создаётся собственно это окно (в примере моветон), так как по хорошему его создание и определение ListView_SetExtendedListViewStyle нужно было размещать в case WM_CREATE: а не так как здесь после MSG msg; перед while(GetMessage(&msg, NULL, 0, 0) > 0). На практике между этими двумя строками ничего не должно быть.
Я размесил эго создание между этим двумя строчками, так как хотел продемонстрировать его включение по кнопке. А как включать это окно, если оно расположено на своём месте в case WM_CREATE: я показать не готов (кнопка в case WM_COMMAND: получает не инициализированный hWndListView), возможно другие участники смогу подсказать как это сделать корректно.

Если же окно нужно строить не на Win32 API, тогда, учитывая что версия MSVC от 6 до 9, его нужно строить с использованием библиотек MFC. Это ещё проще, так как это можно сделать визуально, перетягивая соответственные элементы управления.

student_po 23-08-2009 19:55 1201351

Интересный текст :up . Есть над чем задуматся и поработать. Ну в обшем спасибо за программу и поянительное дополнение. :)

ganselo 23-08-2009 21:13 1201417

Код:

int SearchText (LPCSTR lpFilename,
                LPCSTR lpTextToFind,
                bool bCaseSens,
                bool bContinueSearch,
                void FunctionToCall(HANDLE hFile, DWORD dwOffset, DWORD dwSize))
{
        //для начала выясним, скок ж букв в слове, которое найти надо
        unsigned int uTextLength = (int)strlen(lpTextToFind);
        //и так приступим :) сначала нам надо открыть файл для поиска ;)
        HANDLE hFile = CreateFile ( lpFilename,                //Это имя нашего файла
                                    GENERIC_READ|GENERIC_WRITE, //Мы его хотим читать и писать
                                    FILE_SHARE_READ,            //Разрешим другим прогам наш файл читать
                                    NULL,                      //И никаких атрибутов безопасности нам не надо
                                    OPEN_EXISTING,              //Тек-с...надо открыть существующий файл
                                                                //и если этого сделать не выйдет, то вывалится с ошибкой ;)
                                    FILE_FLAG_SEQUENTIAL_SCAN,  //А это такой ужжжас ;) Скажем операционке, что хотим
                                                                //читать файл от начала и до конца последовательно;)
                                    NULL);                      //Ну и всяких темплейтов на не надо
        //открылся ли файл?
        if (hFile == INVALID_HANDLE_VALUE)
        {
                DWORD dwError = GetLastError ();
                AfxMessageBox ("Оппа...Файл-то и не открылся :(");
                return 0; //не открылся, ну и фиг с ним, выходим из функции
        }

        //Терь придумаем небольшую процедурку для поиска текста ;)
        char* pszBuffer = new char[uTextLength];
        memset (pszBuffer, 0, uTextLength);
        DWORD dwBytesRead = 0;
        DWORD dwOffset = 0;
        unsigned int uCount = 0;
        while (dwOffset + uTextLength <= GetFileSize (hFile, NULL))
        {
                SetFilePointer (hFile, dwOffset, NULL, FILE_BEGIN);
                if (ReadFile (hFile, pszBuffer, uTextLength, &dwBytesRead, NULL))
                {       
                        if (!bCaseSens) {
                        if (!memcmp (&pszBuffer[0], &lpTextToFind[0], uTextLength))
                                if (!bContinueSearch) {
                                        FunctionToCall (hFile, dwOffset, uTextLength);
                                        return 1;
                                } else {
                                        FunctionToCall (hFile, dwOffset, uTextLength);
                                        uCount++;
                                }
                        } else if (!memicmp (&pszBuffer[0], &lpTextToFind[0], uTextLength)) {
                                if (!bContinueSearch) {
                                        FunctionToCall (hFile, dwOffset, uTextLength);
                                        return 1;
                                } else {
                                        FunctionToCall (hFile, dwOffset, uTextLength);
                                        uCount++;
                                }
                        }
                }
                dwOffset++;
        }

        delete [] pszBuffer ;
        CloseHandle (hFile); //закрываем наш файлик ;)

        return uCount;      //Возвращаем количество найденного %)
}

void Funcs (HANDLE hFile, DWORD dwOffset, DWORD dwSize)
{
        static char* pszTest = new char [dwSize];
        memset (pszTest, 64, dwSize);
        DWORD dwBytesWritten;
        SetFilePointer (hFile, dwOffset, NULL, FILE_BEGIN);
        WriteFile (hFile, pszTest, dwSize, &dwBytesWritten, NULL);
        delete [] pszTest
}

void CMFcDlg::OnBnClickedButton1()
{
        SearchText ("c:\\123.TxT", "Lord_Baa", true, 0, Funcs);       
}

lpFilename - это имя файлика, в котором искать бум.
lpTextToFind - текст поиска.
bool bCaseSend - поиск с учетом регистра букв или без онного...
bool bContinueSearch - будет ли наш поиск продолжен после того, как нашли одно слово
void FunctionToCall(HANDLE hFile, DWORD dwOffset, DWORD dwSize) - будит вызвана если текст найден.
в неё передадим дескриптор файла(hFile), смещение от начала файла до начала слова(dwOffset), и длина слова(dwSize)

P.S. Код взят из инета. Ссылки нема(

Serega_Yaroslavl 24-08-2009 02:50 1201550

Cмотря в какой среде разработки нада написать приложение. В том же Borland C++ Builder есть компонент RichEdit который избавляет от рутийной работы с ртф и дос структурой данных

student_po 04-09-2009 15:01 1211448

Цитата:

Цитата Serega_Yaroslavl
Cмотря в какой среде разработки нада написать приложение. »

Visual C++ 6 :)

Admiral 04-09-2009 23:33 1211852

student_po, там тоже возможно использования данного компонента
Using Rich Edit Controls
Пример создания по-русски.


Время: 03:34.

Время: 03:34.
© OSzone.net 2001-