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

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

Ответить
Настройки темы
C/C++ - Кучка (heap)

Аватара для ManHack

Старожил


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

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


Здравствуйте!
Меня интересует как в программе на Си обрабатывать кучу файлов, заданных по маске параметром командной строки как один входной источник? (файлы не копируются друг в друга! в любой момент времени мы должны точно значть из какого именно файла мы считываем)
Синтаксис запуска, например, таков:
myprogram.exe *.TEXT
При таком запуске программа должна обрабатывать в качестве входного потока все файлы с расширением .TEXT, которые лежат в папке с ней.

Товарищи Керниган и Ритчи предлагают только filecopy... ((

Отправлено: 20:51, 13-04-2010

 

Аватара для DillerInc

Обратный инженер


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

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


ManHack, дык, перечислите все файлы в папке, чтобы узнать их кол-во, а после выделите память(можно и кучи можно через VirtualAlloc, зависит от конкретного примера) для таблицы, которая будет содержать структуры следующего типа:
Код: Выделить весь код
opened_file struc
  hFile                         dd   ?  ; Описатель файла, чтобы потом к нему обращаться
  pFileName               dd   ?  ; Указатель на буфер, содержащий путь к файлу
  pFileMem                  dd   ?  ; Указатель на память со считаным файлом
opened_file ends
Для буфера пути файла лучше использовать кучу, т.к. она лучше подходит для выделения небольших размеров памяти.А файл лучше считывать в память, выделенную через VirtualAlloc.
Ну, и далее по обстоятельствам.

-------
То,что неясно,следует выяснить.То,что трудно творить,следует делать с великой настойчивостью. © Конфуций


Отправлено: 22:05, 13-04-2010 | #2



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

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


Аватара для ManHack

Старожил


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

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


Вот про указатели на память со считанным файлом можно поподробнее?
Каким образом это реализуется на Си? Я понимаю что есть "указатель на файл", но фраза "указатель на память" вносит некое смятение в мои мысли. Проясните пожалуйста.

Отправлено: 23:26, 13-04-2010 | #3


Аватара для DillerInc

Обратный инженер


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

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


ManHack, я вам не скажу, как это делается именно на Си, т.к. не пишу на этом языке, но на WinAPI это делается следующим образом:
1. Открываем файл с помощью CreateFile
2. Узнаём размер файла с помощью GetFileSize
3. Выделяем нужное кол-во памяти через VirtualAlloc, основываясь на полученном размере файла
4. И считываем открытый файл в эту память при помощи ReadFile
Вот у вас и получился указатель на память, содержащую считаный файл.
А что такое указатель на файл? Его описатель(который handle)? Если да, то понятие указатель здесь несовсем подходит.

-------
То,что неясно,следует выяснить.То,что трудно творить,следует делать с великой настойчивостью. © Конфуций

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

Отправлено: 00:19, 14-04-2010 | #4


Аватара для ManHack

Старожил


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

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


Спасибо! Но я слышал, что в Си можно совершенно стандартным образом обрабатывать кучу файлов по маске.
Например, в Паскале есть команда, возвращающая первый файл из директории, которые подпадает под заданную маску (к примеру, какую-нибудь такую: ABS*.PAS)
Также там есть команда, которая позволяет получить следующий файл, удовлетворяющий такой маске из той же директории. А далее можно организовать цикл...
В Си тоже есть что-то аналогичное и тоже совершенно стандартное, но упоминаний в руководствах об этом я не нашёл.
Хотелось бы разузнать как такие вещи реализуются именно на Си...

Отправлено: 13:40, 14-04-2010 | #5

pva pva вне форума

Аватара для pva

Ветеран


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

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


Цитата ManHack:
Например, в Паскале есть команда, возвращающая первый файл из директории, которые подпадает под заданную маску (к примеру, какую-нибудь такую: ABS*.PAS) »
я так понял что нужны функции FindFirstFile, FindNextFile, FindClose (windows.h)?
либо findfirst, findnext (dir.h)
в любом случае стандартными их назвать можно только для windows и dos. В юниксе не прокатят.
виндовые функции упоминаются в руководстве msdn, а так же помогает поиск в инете по их названиям.
Ещё пишут что аналогично работает opendir, который есть в юниксе, но меня описание не впечатлило.

А я бы посоветовал, если обработка файлов ведётся независимо, сделать в программе так, чтобы она принимала названия файлов со входного потока, и запускать её так:
dir /s /b /a-d *.pas | my_program
один косяк: у винды глюкавый dir. Если он встретит папку 1.pas, то перечислит всё её содержимое. В юниксе таких проблем нет.
Это сообщение посчитали полезным следующие участники:

Отправлено: 15:33, 14-04-2010 | #6


Ветеран


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

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


pva, для Юникса по идеи должен помочь исходник ls.

Отправлено: 15:39, 14-04-2010 | #7

pva pva вне форума

Аватара для pva

Ветеран


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

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


так и есть, а моя любимая - find и/или grep

Отправлено: 20:52, 14-04-2010 | #8


Аватара для ManHack

Старожил


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

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


На славу потрудившись, я написал следующий код:
Код: Выделить весь код
void ResetText() {
	WIN32_FIND_DATA FindFileData;
	HANDLE hFind;
	hFind = FindFirstFile( Path , &FindFileData );
	puts("FindFileData.cFileName");
	if( FindFileData.cFileName == NULL ) {
		puts("Формат вызова:\n   O <входной файл>");
		exit(1);
	}
	else if( (f = fopen(FindFileData.cFileName, "r")) == NULL ){
		ResetError = TRUE;
		Message = "Входной файл не найден";
	}
	else {
		ResetError = FALSE; Message = "Ok";
		Pos = 0; Line = 1;
		NextCh();
	} 
	do {
		if( hFind  && !( FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY  ) ) {
			if( FindFileData.cFileName == NULL ) {
				puts("Формат вызова:\n   O <входной файл>");
				exit(1);
			}
			else if( (f = fopen(FindFileData.cFileName, "r")) == NULL ){
				ResetError = TRUE;
				Message = "Входной файл не найден";
			}
			else {
				ResetError = FALSE; Message = "Ok";
				Pos = 0; Line = 1;
				NextCh();
			} 
		}			
	} while( FindNextFile( hFind, &FindFileData ) );
	FindClose(hFind);
}
Невероятно, но он компилируется в MS Visual Studio 2008 как код на Си.
Теперь проблема: скармливаю я ему, значит, консольный ввод:
Код: Выделить весь код
MyProgram.exe InputFile.txt
А он мне врёт:
Цитата:
Входной файл не найден
Что я сделал не так?

PS> Как из WIN32_FIND_DATA конвертировать, скажем, в формат массива из символов?

Отправлено: 22:59, 06-05-2010 | #9

pva pva вне форума

Аватара для pva

Ветеран


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

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


1) что такое Path? откуда он взялся?
2) посоветую изначально занулить WIN32_FIND_DATA
3) насколько я помню, cFileName - это и есть массив из MAX_PATH_LENGTH символов (а не указатель), поэтому
Цитата ManHack:
if( FindFileData.cFileName == NULL ) { »
никогда не сработает
Это сообщение посчитали полезным следующие участники:

Отправлено: 12:57, 08-05-2010 | #10



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

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

Похожие темы
Название темы Автор Информация о форуме Ответов Последнее сообщение
heap @ c++ stl pva Программирование и базы данных 10 12-04-2005 15:58




 
Переход