Имя пользователя:
Пароль:  
Помощь | Регистрация | Забыли пароль?  | Правила  

Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Поиск текста в файлах

Ответить
Настройки темы
C/C++ - Поиск текста в файлах

Новый участник


Сообщения: 19
Благодарности: 2

Профиль | Отправить PM | Цитировать


Изменения
Автор: student_po
Дата: 12-08-2009
Доброго времени суток. В институте дали задания написать программу, которая должна искать текст в файлах (типа поиска в 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. Но если нет, то и на других языках пойдет.
Это сообщение посчитали полезным следующие участники:

Отправлено: 11:46, 12-08-2009

 

Ветеран


Сообщения: 3320
Благодарности: 916

Профиль | Отправить PM | Цитировать


Доброго времени суток 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. Это ещё проще, так как это можно сделать визуально, перетягивая соответственные элементы управления.

Последний раз редактировалось Admiral, 13-08-2009 в 00:44.

Это сообщение посчитали полезным следующие участники:

Отправлено: 23:42, 12-08-2009 | #2



Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

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


Новый участник


Сообщения: 19
Благодарности: 2

Профиль | Отправить PM | Цитировать


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

Отправлено: 19:55, 23-08-2009 | #3


Аватара для ganselo

Старожил


Сообщения: 232
Благодарности: 90

Профиль | Сайт | Отправить PM | Цитировать


Код: Выделить весь код
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. Код взят из инета. Ссылки нема(

-------
К величайшему сожалению "история учит нас тому, что она ничему не учит".

Это сообщение посчитали полезным следующие участники:

Отправлено: 21:13, 23-08-2009 | #4


Новый участник


Сообщения: 13
Благодарности: 3

Профиль | Отправить PM | Цитировать


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

Отправлено: 02:50, 24-08-2009 | #5


Новый участник


Сообщения: 19
Благодарности: 2

Профиль | Отправить PM | Цитировать


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

Отправлено: 15:01, 04-09-2009 | #6


Ветеран


Сообщения: 3320
Благодарности: 916

Профиль | Отправить PM | Цитировать


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

Отправлено: 23:33, 04-09-2009 | #7



Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Поиск текста в файлах

Участник сейчас на форуме Участник сейчас на форуме Участник вне форума Участник вне форума Автор темы Автор темы Шапка темы Сообщение прикреплено

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
Поиск текста и выполнение действий!!! Giena22 AutoIt 5 23-09-2009 20:21
Поиск одинаковых кадров в видео-файлах wale Видео и аудио: обработка и кодирование 2 11-04-2009 22:00
[решено] Поиск нужного текста в html коде страницы ph0en1x AutoIt 8 16-02-2009 02:38
Вопросняк о файлах Aqwertyu Хочу все знать 2 29-01-2003 11:01
О файлах *.tmp Niki Microsoft Windows 95/98/Me (архив) 4 04-02-2002 21:12




 
Переход