Re: Что творится с памятью?
От: alexelev  
Дата: 01.06.13 14:46
Оценка:
Здравствуйте, alexelev, Вы писали:

A>Дано:

A>куча файлов вида (Untitled001.pdf, Untitled002.pdf, Untitled003.pdf ...) в количестве более 800 штук;
A>строки вида (I-А-1, I-А-2, I-А-3, I-А-4, I-А-5, ... ), каждая из которых содержится в одном из кучи файлов.

A>Найти:

A>в каком файле содержится какая строка, например "I-А-1 Untitled012.pdf, I-А-2 Untitled117.pdf, ..." и вывести это в файл (исключительно для удобства)

A>Мой (нерабочий) вариант решения проблемы:



A>
A>#include <iostream>
A>#include <cstring>
A>#include <ctime>
A>#include <direct.h>
A>#include <string.h>
A>#include <cstdlib>
A>#include <cstdio>
A>#include <fstream>
A>#include <io.h>
A>#include <stdio.h>
A>using namespace std;
A>void main()
A>{
A>    //файл, куда будет выводится инфа
A>    FILE* rslt = _fsopen("E:\\TEST\\rslt.txt", "w", _SH_DENYNO);


A>    for(int i = 0; i < 1000; i ++)
A>    {
A>        //лепим имя файла
A>        char fp[256] = {0};

A>        if (i < 9)
A>            strcpy_s(fp,256,"E:\\TEST\\det\\Untitled00");
A>        else if (i < 99)
A>            strcpy_s(fp,256,"E:\\TEST\\det\\Untitled0");
A>        else
A>            strcpy_s(fp,256,"E:\\TEST\\det\\Untitled");


A>        char buf[256] = {0};
A>        _itoa_s(i+1, buf, 256, 10);
A>        strcat_s(fp,256,buf);
A>        strcat_s(fp,256,".pdf\0");
A>        //на выходе имеем путь к файлу вида "E:\\TEST\\det\\Untitled001.pdf"
        
A>        //открываем файл
A>        FILE* fn = _fsopen(fp, "r", _SH_DENYNO);
        
A>        //пытаемся определить его объём - количество символов файла
A>        int a = _fileno(fn); //именно тут происходим какая-то ошибка с памятью
A>        long size = _filelength(_fileno(fn));
        
A>                //переводим все содержимое файла в буфер
A>        char* buffer = new char [size];
A>        fgets(buffer, size, _fsopen(fp, "r", _SH_DENYNO));
        
A>        for (int j = 0; j < 1000; j ++)
A>        {
A>            //формируем искомую подстроку
A>            char numb[10] = {0};
A>            _itoa_s(j+1, numb, 256, 10);
A>            char name[256] = {0};
A>            strcat_s(name, 256, "I-А-");
A>            strcat_s(name, 256, numb);
A>            //на выходе имеем строку вида "I-А-1"

A>            //находим вхождение искомой строки в буфферном массиве и если есть - записываем в файл соответствие 
A>            if (strstr(buffer, name) != NULL)
A>            {
A>                char temp[256] = {0};
A>                strcat_s(temp, 256, name);
A>                strcat_s(temp, 256, "\t");
A>                strcat_s(temp, 256, fp);
A>                fputs(temp, rslt);
A>            }
A>        }
A>        fclose(fn);
A>    }
A>    _fcloseall();
A>}

A>


A>Хотя код следующего вида выполняется на ура:



A>
A>cout << _filelength(_fileno(_fsopen("E:\\TEST\\det\\Untitled001.pdf", "r", _SH_DENYRD))) << endl;
A>


переписал код:
#include <iostream>
#include <cstdio>
#include <io.h>
#include <Windows.h>
#include <ctime>

void main()
{
    SetConsoleCP(1251);
    SetConsoleOutputCP(1251);

    time_t start, end, result;
    struct _finddata_t txt_file;
    long hFile;
    int count = 0;

    time(&start);
    FILE* rslt = _fsopen("E:\\TEST\\result.txt", "w", _SH_DENYNO);

    /* определяем количество .txt файлов */
    if( (hFile = _findfirst( "E:\\TEST\\det_text\\*.txt", &txt_file )) == -1 )
        printf( "No *.txt files in current directory!\n" );
    else
    {
        count = 1;
        //printf_s("%s\n", txt_file.name);
        /* Find the rest of the .txt files */
        while( _findnext( hFile, &txt_file ) == 0 )
        {
            count ++;
            //printf_s("%s\n", txt_file.name);
        }
        _findclose( hFile );
        printf_s("найдено %d файлов для поиска\n", count);
    }
    
    for (int i = 0; i < count; i ++)
    {
        char fn[256] = {0};
            
        if(sprintf_s(fn, "E:\\TEST\\det_txt_ansi\\Untitled%03d.txt", i + 1) == 0 &&
            sprintf_s(fn, "E:\\TEST\\det_txt_ansi\\Untitled%03d.txt", i + 1) == -1)
        {
            printf_s("Ошибка создания пути файла Untitled%03d.txt при поиске\n", i + 1);
            break;
        }
        FILE* f = _fsopen(fn, "r", _SH_DENYRD);
        if(!f)
        {
            printf_s("Ошибка открытия файла Untitled%03d.txt\n", i + 1);
            break;
        }
        int size = _filelength(_fileno(f));

        /*переписываем содержимое файла в буферную строку*/
        char* tmp = new char [size];
        
        for (int j = 0; j < size && tmp[j] != EOF; j ++)
        {
            tmp[j] = fgetc(f);
        }
        fclose(f);

        /*поиск искомой строки и считывание следующих символов до конца строки*/
        for (int k = 0; k < size; k ++)
        {
            char SubStr[20] = "I-А-";
            if(tmp[k] == SubStr[0])
            {
                for(int n = 1; n < size; n ++)
                {
                    if(SubStr[n] == 0 && tmp[k + n] != 10)
                        SubStr[n] = tmp[k + n];
                    else if(tmp[k + n] == '\n' && SubStr[n] == 0)
                    {
                        fprintf_s(rslt, "%s\t\t%s\n", SubStr, fn);
                        break;
                    }
                    if (tmp[k + n] != SubStr[n]) 
                        break;
                }
            }
        }
        delete [] tmp;
    }
    
    _fcloseall();
    time(&end);
    result = end - start;
    printf_s("РАБОТА ПРОГРАММЫ УСПЕШНО ЗАВЕРШЕНА!\nвремя работы программы %d сек\n", result);
}


Благодарю особо @Кодт и @watch-maker за помощь и направление движения мыслей. Хотя остается еще ряд нерешенных проблем. В таком виде, как я формулировал задачу, выполнить ее я не смог по причине того, что обрабатываемые файлы — .pdf. Как выяснилось методом проб и ошибок пдф-файлы открываются как текстовые, но искомый ключ в них не находится, а при выводе считанного из пдф-файла получается какой-то мусор. Так что пришлось конвертировать пдф в текст, текст получался юникод, так что приходилось его переконвертировать в ANSI, только тогда данный способ работает. Теперь ломаю голову, как бы сделать так, чтобы избежать всех этих многочисленных переконвертаций, а читать и искать сразу непосредственно в пдф-файлах. Может кто-нибудь подсказать, куда копать для этого?
З.Ы. @Кодт указал прелестный способ для юникс-окружения, а можно что-либо подобное выполнить в cmd Windows используя команды find/findstr?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.