PDA

Показать полную графическую версию : Помогите найти загвоздку в циклах


Apock
06-09-2012, 22:39
Есть следующая задача: получить из определённой папки список вложенных в неё папок(один уровень). В них находятся текстовые документы. Нужно, при нажатии на кнопку, внести в базу полные пути файлов и количество их строк из некоторых вложенных папок. Делается всё в С++ Builder 6.0.

void __fastcall TForm1::Button1Click(TObject *Sender)
{
TStringList *list = new TStringList; //для хранения содержимого файла
int cnt; //число строк в файле
int i=0; //для цикла while
DirectoryListBox1->Directory=direct; //установка начальной папки, заранее определённой в direct
while(i < DirectoryListBox1->Count)
{
dir=DirectoryListBox1->Items->Strings[i]; //берём по очереди названия вложенных папок
if(dir[1]='2') //нам нужны только папки, начинающиеся на "2"
{
FileListBox1->Directory=direct+"\\"+dir; //получаем список файлов в папке
for(int z=0; z<FileListBox1->Count; z++) //приступаем к их обработке
{
list->LoadFromFile(DirectoryListBox1->Directory+"\\"+FileListBox1->Items->Strings[z]); //получаем содержимое файла
cnt=list->Count; //считаем кол-во строк
ADOTable1->Insert(); //добавляем данные в базу
ADOTable1->FieldByName("FilePath")->AsString=DirectoryListBox1->Directory+"\\"+FileListBox1->Items->Strings[z];
ADOTable1->FieldByName("Lines")->AsInteger=cnt;
ADOTable1->Post();
}
}
i++;
}
}

Проблема в том, что в базу вносятся только файлы из первой папки, начинающейся с "2". В моём случае таких папок 5. Думал проблема с вложенными циклами(изначально оба были for). Поменял на while - не помогло.
Поставил в конце первого цикла вывод переменной i на Label и секундную паузу, чтоб проследить за выполнением цикла. DirectoryListBox1 содержит 11 папок. При запуске цикла программа некоторое время не отвечает, затем цикл закрывается, на Label цифра 7, а в базе опять таки те же файлы из первой папки.
В принципе проблема решается разделением циклов. Делаем, к примеру, скрытый компонент Memo. В него вносим названия папок первым циклом. Вторым уже пробегаемся по файлам. Так работает, но мне такой подход кажется нерациональным. И интересно всё-таки, что ж за загвоздка в данном коде?

lxa85
07-09-2012, 06:02
Вот же прям строка кода:
if(dir[1]='2') //нам нужны только папки, начинающиеся на "2" »
Проблема в том, что в базу вносятся только файлы из первой папки, начинающейся с "2". »

Apock
07-09-2012, 12:09
Ну так это условие отбора папок. Нашёл папку, начинающуюся на "2", обработал, занёс в базу. Дальше инкримент увеличивается и в dir должно попасть имя следующей папки из DirectoryListBox1.

lxa85
07-09-2012, 12:51
Apock, а можно заполучить проект (пусть урезанный) и тестовый набор папок?
Я хоть трассировку сделаю.


P.S. В воскресенье я исчезну на неделю. Т.ч. времени совсем чуть-чуть или "до послезавтра".

pva
07-09-2012, 13:36
Я вот может что-то не понимаю.
if(dir[1]='2') »
Это начинается на '2' или второй символ '2'? А ещё
явный выход за границы (не проверяется, достаточно ли в строке символов). Хотя в борландовской строке вроде оператор [] выдаёт исключение, если что-то не так.

Apock
08-09-2012, 16:30
dir - строка AnsiString, которой присваивается имя каталога. [1] - указатель на первый символ строки.
Имена папок пустыми быть не могут, поэтому проверять число символов в принципе не важно.

Вообще правильнее будет dir[1]=='2'. Исправил, но это не даёт нужного результата.

Что-то вообще запутался. На втором пк стоит c++ builder XE. Перенёс проект туда. Он ищет файлы в папке на уровень выше почему-то, а их там естественно нет. Пришлось изменить строку
DirectoryListBox1->Directory+"\\"+FileListBox1->Items->Strings[z] »
на DirectoryListBox1->Directory+"\\"+dir+"\\"+FileListBox1->Items->Strings[z].
После этого поиск прошёл правильно и в базу попали файлы из всех папок.
Этого момента с папками так и не понял, но получается, что всё-таки проблема какая-то с работой вложенных друг в друга циклах для Builder6 есть.

lxa85
08-09-2012, 19:29
Apock, можно заполучить проект (пусть урезанный) и тестовый набор папок? »
Мне действительно лень писать проект с нуля и создавать иерархию папок, что бы проверить цикл.
Будет исходник и проверочные данные - проблем нет.
В противном случае, я найду чем заняться. Без обид, но вы не способствуете тому, чтобы мы вам помогли.

Apock
09-09-2012, 15:18
Это я да, тормознул чего-то. Занялся тестами на BuilderXE и забыл обо всём.
Внутри файлик с комментами.

lxa85
15-09-2012, 01:13
Проект скачал. Как появится окно(ориентировочно в воскресенье после обеда), посмотрю, что да как.

El Scorpio
17-09-2012, 04:05
dir - строка AnsiString, которой присваивается имя каталога. [1] - указатель на первый символ строки. »
Вообще-то индекс [1] указывает на второй элемент массива. Не забывайте, что нумерация идёт с нуля, то есть "первым" (для человека некомпьютерного) элементом массива является элемент со смещением [0]

Делаем, к примеру, скрытый компонент Memo. »
Зачем? Чтобы сохранить список строк достаточно создать объект класса TStringList.

Apock
17-09-2012, 22:53
Если это второй элемент, то странно. Как он тогда вообще какие-то данные находит. Ни одной папки с вторым символом "2" нет.
А с Мемо это я так. Привычно просто наблюдать за всем происходящим, пока программу пишешь.




© OSzone.net 2001-2012