C/C++ - Кучка (heap)

Аватара пользователя
ManHack

C/C++ - Кучка (heap)

Сообщение ManHack »

Здравствуйте!

Меня интересует как в программе на Си обрабатывать кучу файлов, заданных по маске параметром командной строки как один входной источник? (файлы не копируются друг в друга! в любой момент времени мы должны точно значть из какого именно файла мы считываем)

Синтаксис запуска, например, таков:

myprogram.exe *.TEXT

При таком запуске программа должна обрабатывать в качестве входного потока все файлы с расширением .TEXT, которые лежат в папке с ней.



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

Re: C/C++ - Кучка (heap)

Сообщение DillerInc »

ManHack, дык, перечислите все файлы в папке, чтобы узнать их кол-во, а после выделите память(можно и кучи можно через VirtualAlloc, зависит от конкретного примера) для таблицы, которая будет содержать структуры следующего типа:



Код:

Код: Выделить всё

opened_file struc
  hFile                         dd   ?  ; Описатель файла, чтобы потом к нему обращаться
  pFileName               dd   ?  ; Указатель на буфер, содержащий путь к файлу
  pFileMem                  dd   ?  ; Указатель на память со считаным файлом
opened_file ends

Для буфера пути файла лучше использовать кучу, т.к. она лучше подходит для выделения небольших размеров памяти.А файл лучше считывать в память, выделенную через VirtualAlloc.

Ну, и далее по обстоятельствам.
Аватара пользователя
ManHack

Re: C/C++ - Кучка (heap)

Сообщение ManHack »

Написал совсем по-человечески:

O.C



Код:

Код: Выделить всё

/* Љ®¬ЇЁ«пв®а п§лЄ* Ћ (o.c) */
#define _CRT_SECURE_NO_WARNINGS 
#include <stdlib.h>
#include <stdio.h>
#include <io.h>
#include <time.h>
#include <string.h>
#include "text.h"
#include "scan.h"
#include "scan.h"
#include "location.h"
#include "pars.h"
#include "error.h"
void Init(void) {
	ResetText();
	if( ResetError )
		Error(Message);
	InitScan();
}
void Done(void) {
   CloseText();
}
int main(int argc, char *argv[]) {
   struct _finddata_t c_file;
   intptr_t hFile;
   puts("\n бла-бла-бла");
   if( argc <= 1 )
      Mask = NULL;
   else
      Mask = argv[1];
   hFile = _findfirst( Mask, &c_file );
   if( (hFile = _findfirst( Mask, &c_file )) == -1L ) {
	   printf( "%s", "Файлов, удовлетворяющих маске " );
	   printf( "%s", Mask );
	   printf( "%s", "не найдено.\n" );
   } else {
	   do {
		   strcpy(Path, &c_file.name);
		   Init();    
		   Compile(); 
                           Done();
	   } while( _findnext( hFile, &c_file ) == 0 );
	   _findclose( hFile );
   }
   return 0;
}

Этот самый ResetText():



Код:

Код: Выделить всё

char ResetError = TRUE;
char* Message = "”*©« *Ґ ®вЄалв";
int Ch = chEOT;
static FILE *f;
void NextCh() {
   if( (Ch = fgetc(f)) == EOF )
      Ch = chEOT;
   else if( Ch == '\n' ) {
        //readln(f);// ??
	   // puts("");
      Line++; Pos = 0; Ch = chEOL;
      }
   else if( Ch == '\r' )
      NextCh();
   else if( Ch != '\t' ) {
      //  putchar(Ch); 
	   Pos++;
      }
    // else
       // do
       //    putchar(' ');
      //  while( ++Pos % TABSIZE );
}
void ResetText() {
	if( Path == NULL ) {
		puts("Запуск*:\n   MyProgram.exe <вход. файл>");
		exit(1);
	}
	else if( (f = fopen(Path, "r")) == NULL ){
		ResetError = TRUE;
		Message = "Что-то пошло не так с открытием файла*";
	}
	else {
		ResetError = FALSE; Message = "Ok";
		Pos = 0; Line = 1;
		NextCh();
	}
}



Теперь первый файл по маске программа читает нормально, а вот когда под маску подпадают несколько файлов, то когда дело доходит до второго возникает ошибка:



Изображение





Ошибка возникает на втором файле, т.к. я пробовал выводить значение переменной Path когда они присваиваются - выдало 1-е имя файла из папки, удовлетворяющее маске и 2-е, потом ошибка.



В чём причина неполадки? Почему программа не хочет обрабатывать последующие файлы? (их имена она определяет правильно)

При компиляции проекта в MS Visual Studio 2008 ошибок не возникало... Помогите.
Аватара пользователя
ManHack

Re: C/C++ - Кучка (heap)

Сообщение ManHack »

Вот про указатели на память со считанным файлом можно поподробнее?

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

Re: C/C++ - Кучка (heap)

Сообщение DillerInc »

ManHack, я вам не скажу, как это делается именно на Си, т.к. не пишу на этом языке, но на WinAPI это делается следующим образом:

1. Открываем файл с помощью CreateFile

2. Узнаём размер файла с помощью GetFileSize

3. Выделяем нужное кол-во памяти через VirtualAlloc, основываясь на полученном размере файла

4. И считываем открытый файл в эту память при помощи ReadFile

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

А что такое указатель на файл? Его описатель(который handle)? Если да, то понятие указатель здесь несовсем подходит.
Аватара пользователя
ManHack

Re: C/C++ - Кучка (heap)

Сообщение ManHack »

Цитата ManHack:



Например, в Паскале есть команда, возвращающая первый файл из директории, которые подпадает под заданную маску (к примеру, какую-нибудь такую: ABS*.PAS)
C/C++ - Кучка (heap)




я так понял что нужны функции FindFirstFile, FindNextFile, FindClose (windows.h)?

либо findfirst, findnext (dir.h)

в любом случае стандартными их назвать можно только для windows и dos. В юниксе не прокатят.

виндовые функции упоминаются в руководстве msdn, а так же помогает поиск в инете по их названиям.

Ещё пишут что аналогично работает opendir, который есть в юниксе, но меня описание не впечатлило.



А я бы посоветовал, если обработка файлов ведётся независимо, сделать в программе так, чтобы она принимала названия файлов со входного потока, и запускать её так:

dir /s /b /a-d *.pas | my_program

один косяк: у винды глюкавый dir. Если он встретит папку 1.pas, то перечислит всё её содержимое. В юниксе таких проблем нет.
Аватара пользователя
pva

Re: C/C++ - Кучка (heap)

Сообщение pva »

pva, для Юникса по идеи должен помочь исходник ls.
Аватара пользователя
Admiral

Re: C/C++ - Кучка (heap)

Сообщение Admiral »

pva, для Юникса по идеи должен помочь исходник ls.
Аватара пользователя
Admiral

Re: C/C++ - Кучка (heap)

Сообщение Admiral »

так и есть, а моя любимая - find и/или grep
Аватара пользователя
pva

Re: C/C++ - Кучка (heap)

Сообщение pva »

1) что такое Path? откуда он взялся?

2) посоветую изначально занулить WIN32_FIND_DATA

3) насколько я помню, cFileName - это и есть массив из MAX_PATH_LENGTH символов (а не указатель), поэтому
Цитата ManHack:



if( FindFileData.cFileName == NULL ) {
C/C++ - Кучка (heap)




никогда не сработает
Ответить

Вернуться в «Программирование и базы данных»