Здравствуйте, 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?