Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: FindFirstFileEx/FindNextFile  (Прочитано 21674 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« : 30-09-2011 11:12 » new

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

(слева - моё дерево, справа - проводниковое)
содержимое папки C:\1111111111\2\3\  показано верно (она первая была просмотрена) , а вот папка C:\1111111111\3  показывает то же самое, что в предыдущей, хотя там совсем не то



И как же этот рекурсивный поиск сделать, неужели вытаскивать содержимое по одной папке, затем по этим файлам пробегаться снова и заходить в каждую папку ?

* recurs1.PNG (6.63 Кб - загружено 1837 раз.)
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 30-09-2011 11:21 » 

Леш, вероятно ты использовал имя папки как идентификатор ассоциативного массива. Тогда уж используй в качестве ключа полный путь.
А как еще без рекурсии?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #2 : 30-09-2011 11:24 » 

нет, я строю дерево вообще-то, а не просто ассоциативный массив заполняю. Я не против рекурсии, но как-то она тут не вышла )

Добавлено через 7 минут и 38 секунд:
кстати, если вторую папку 3 переименовать (скажем в 5) , то содержимое папки 5 совсем не удаётся узнать.
« Последнее редактирование: 30-09-2011 11:32 от Алексей1153 » Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 30-09-2011 11:32 » 

Покажи...
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #4 : 30-09-2011 11:36 » 

Sla, минутку, нужно функцию рафинировать, чтобы показать )

Добавлено через 27 минут и 21 секунду:
вот, убрал лишнее, результат выводится в трейс (без отступов)
Код:
	void PrintDirs(const WCHAR* path_)
{
if(!path_)
{
path_=L"";
}

if(path_[0])
{
std::wstring fullpath__;
WIN32_FIND_DATA WFD={0};

fullpath__=path_;
if(!fullpath__.empty() && *fullpath__.rbegin()!=L'\\')
{
fullpath__.push_back(L'\\');
}
fullpath__.push_back(L'*');

HANDLE F=::FindFirstFileEx
(
fullpath__.c_str()
,FindExInfoStandard
,&WFD,FindExSearchNameMatch
,0
,0
);

//убираем звёздочку
if(!fullpath__.empty())
{
fullpath__.erase(fullpath__.size()-1);
}

do
{
const bool isdir=((WFD.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0);

if(isdir)
{
if(WFD.cFileName[0]==L'.')
{
if(WFD.cFileName[1]==0)continue;
if(WFD.cFileName[1]==L'.')
{
if(WFD.cFileName[2]==0)continue;
}
}
}

if(isdir)
{
if(!fullpath__.empty() && *fullpath__.rbegin()!=L'\\')
{
fullpath__.push_back(L'\\');
}
fullpath__+=WFD.cFileName;

PrintDirs(fullpath__.c_str());
}
else
{
//WFD.cFileName
}

TRACE("\r\n");
TRACE(WFD.cFileName);


}
while(::FindNextFile(F,&WFD));
::FindClose(F);
}
}

Добавлено через 10 минут и 59 секунд:
блин, у меня такое чуйство, что у меня где-то косяк, но не пойму, где

Добавлено через 4 минуты и 54 секунды:
трейс тоже радует

Код:
4
_CrtDbgReport: String too long or IO Error
3
2

а там всего лишь имя файла выводится "текстовый документ.txt"


аааааа, я сегодня блондин )))  Где-то я явно что-но накосячил с памятью...
« Последнее редактирование: 30-09-2011 12:03 от Алексей1153 » Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 30-09-2011 12:35 » 

Алексей1153++,
шо ты здесь накрутил...


Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 30-09-2011 14:14 » 

Sla, что не так ?
Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 30-09-2011 14:22 » 

наверное все так...
Ты как-то не сильно и рафинировал код

Printdir()
{
findfirst
do
   if is_dir {Printdir}
while findnext
}

И весь код... А у тебя много, на мой взгляд, мусора
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 30-09-2011 14:32 » 

Sla, весь мусор там связан с тем, что с путём надо няньчится

Можно и так (только две лишние директории появятся в списке)

Код:
	void PrintDirs(const WCHAR* path_)
{
std::wstring fullpath__;
WIN32_FIND_DATA WFD={0};

fullpath__=path_;
if(!fullpath__.empty() && *fullpath__.rbegin()!=L'\\')
{
fullpath__.push_back(L'\\');
}
fullpath__.push_back(L'*');

HANDLE F=::FindFirstFileEx
(
fullpath__.c_str()
,FindExInfoStandard
,&WFD,FindExSearchNameMatch
,0
,0
);

//убираем звёздочку
if(!fullpath__.empty())
{
fullpath__.erase(fullpath__.size()-1);
}

do
{
if(WFD.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)
{
fullpath__+=WFD.cFileName;

PrintDirs(fullpath__.c_str());
}

TRACE("\r\n");
TRACE(WFD.cFileName);

fullpath__.push_back(L'\\');
}
while(::FindNextFile(F,&WFD));
::FindClose(F);
}
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #9 : 30-09-2011 14:47 » 

Алексей1153++, гонишь.

Код: (C++)
#include <iostream>
#include <string>
#include <windows.h>

using namespace std;

void outtree(int level, wstring &path);

void procitem(int level, wstring &path, WIN32_FIND_DATA &findFileData)
{
        wstring fileName = wstring(findFileData.cFileName);
        if(fileName.compare(L".") != 0 && fileName.compare(L"..") != 0)
        {
                for(int i = 0; i < level; i += 1)
                {
                        wcout << L" ";
                }
                wcout << fileName << endl;
                if((findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
                {
                        outtree(level + 1, path + wstring(L"\\") + fileName);
                }
        }
}

void outtree(int level, wstring &path)
{
        WIN32_FIND_DATA findFileData;
        wstring searchPath = path + wstring(L"\\*");
        HANDLE searchHandle = FindFirstFileEx(searchPath.c_str(), FindExInfoStandard, &findFileData, FindExSearchNameMatch, NULL, 0);
        if(searchHandle != INVALID_HANDLE_VALUE)
        {
                procitem(level, path, findFileData);
                while(FindNextFile(searchHandle, &findFileData) != 0)
                {
                        procitem(level, path, findFileData);
                }
                FindClose(searchHandle);
        }
}

int main(int argc, char *argv[])
{
        outtree(0, wstring(L"C:\\Test"));
        getchar();
        return 0;
}
11
 2
  3
   4
    tt.txt
 3
  t.txt
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 30-09-2011 14:55 » 

Алексей1153++, зачем нянчиться?
Понятно , что .. и . нужно пропускать
Мною показанный "код" - чем тебя не устраивает.
И причем здесь нереентерабелность findnext?   
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #11 : 30-09-2011 15:06 » 

Dimka, я в курсе, вот и хочу понять, в каком именно моменте
Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #12 : 30-09-2011 15:18 » 

Алексей1153++, упрощай
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #13 : 30-09-2011 15:29 » 

не, Слав, там нечего упрощать, мне всё так надо.  Всё, ошибку нашёл, это я переработался, похоже Жаль

Димке спасибо за намёк

вот тут я херню сморозил
Код:
fullpath__+=WFD.cFileName;

путь портился для поиска следующих элементов
Записан

zubr
Гость
« Ответ #14 : 30-09-2011 16:34 » 

Кстати, если посмотреть в отладчике на работу проводника, то будет видно, что он использует те же FindFirst /FindNext
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #15 : 30-09-2011 16:56 » 

zubr, в АПИ вроде нет таких функций. Или я не нашёл
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 30-09-2011 18:26 » 

http://msdn.microsoft.com/en-us/library/windows/desktop/aa364418%28v=vs.85%29.aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa364428%28v=vs.85%29.aspx

Леш, уже пятница! Пора отдыхать Пиво!
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
zubr
Гость
« Ответ #17 : 30-09-2011 19:05 » 

Алексей1153++, ну я их сокращенно написал, опуская окончание File Улыбаюсь
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #18 : 30-09-2011 19:35 » 

RXL, Ром, эти то я нашёл ))

Да и какая тяпница, у меня круглый день - рабочий. Вот сижу слушаю одну из любимых композиций с psyradio
http://www.youtube.com/watch?v=W3q5sRcUwR0=player_embedded
Записан

Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #19 : 30-09-2011 20:19 » 

Цитата: Алексей1153++
путь портился для поиска следующих элементов
Переменные делятся на входные и выходные (параметры), а также локальные. Есть хорошее правило - не менять значениях входных параметров.

Однако, чтобы этим хорошим правилом воспользоваться, ещё надо уметь делать декомпозицию по функциям. И не только уметь, но и хотеть этим заниматься.

Можно и с другой стороны зайти. Определить, какие переменные характеризуют состояние объекта или процесса в пространстве состояний, а какие - лишь вспомогательные для расчётов. Затем взять за правило делить код на расчётный и отвечающий за смену состояний (управляющий), вынося расчёты в отдельные функции или вспомогательные объекты.

Короче говоря, есть хорошие привычки, следование которым полностью исключает такого рода ошибки, даже когда пятница, заработался и голова дурная, т.к. привычка - это тоже "автоматизм", и участие головы в его реализации минимально.
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #20 : 02-10-2011 05:03 » 

Dimka, учтём )
Записан

dark_rain
Помогающий

ua
Offline Offline
Пол: Мужской

« Ответ #21 : 01-11-2011 21:07 » 

Извиняюсь если не в тему, но для подобных вещей boost::filesystem мега круто.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #22 : 02-11-2011 09:35 » 

бустом не пользуюсь как-то )
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines