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

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: Генерация дерева каталогов С++ без API  (Прочитано 33491 раз)
0 Пользователей и 7 Гостей смотрят эту тему.
TJ
Гость
« : 07-06-2008 08:02 » 

Надо сгенерировать дерево каталогов заданого диска не важно какого(неважно в какой форме псевдо графике или там в файл записать), но без использования API , создать свой класс или метод. С помощью апи то я справился, но препод сказал что мол пацик не катит такая шняга для первокласников.  НУЖНА ПОМОЩЬ!!!!!!!!!!!!!!!
 Просто возникли проблемы:
 1.Как обращатся к диску
 2.Как находить потом на нём инфу

Поправил название.
Делаю предупреждение: прочти правила.
« Последнее редактирование: 08-06-2008 07:37 от RXL » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #1 : 07-06-2008 08:21 » new

скажи преподу, что он не прав Улыбаюсь
Если АПИ не катит - то пусть катиться препод
Записан

PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #2 : 07-06-2008 08:27 » 

TJ, жми кнопку редактировать на первом сообщении и убирай капс из названия, дабы тему не потерли.
Алексей1153++, смотря что препод понимает под API, точнее какой именно API его не устраивает...
TJ, что именно ты использовал для решения задачи?
... можно в общем-то и напрямую с FAT работать... если в задании есть такое условие.
Записан

Удачного всем кодинга! -=x[PooH]x=-
sss
Специалист

ru
Offline Offline

« Ответ #3 : 07-06-2008 08:31 » 

PooH, для начала написать прямую работу с IDE/SATA портами  Да что ты говоришь?..

Серьезно, наверное TJ вывел OpenDialog и все... А ему как раз надо API.
Записан

while (8==8)
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #4 : 07-06-2008 08:35 » 

не знаю как в Windows, а в Linux это делается на раз, два, три Улыбаюсь
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #5 : 07-06-2008 08:36 » 

sss, для начала юзать asm, а уже потом в IDE/SATA можно переходить =) Ага
« Последнее редактирование: 07-06-2008 08:39 от PooH » Записан

Удачного всем кодинга! -=x[PooH]x=-
PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #6 : 07-06-2008 08:38 » 

McZim, что именно? и каким образом, если не использовать никакое API? Отлично
sss, я тоже склоняюсь к тому, что для решения задачи был просто вызван SHBrowseForFolder... поэтому и спросил как именно была решена задача.
Записан

Удачного всем кодинга! -=x[PooH]x=-
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #7 : 07-06-2008 08:43 » 

PooH, могу ошибаться в терминологии, но работа с HDD в линуксе сводится к стандартным функциям работы с файлами open() read() write(). Является ли это API?
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
sss
Специалист

ru
Offline Offline

« Ответ #8 : 07-06-2008 08:48 » 

McZim, конечно. Та же не задумываешься от типе файловой системы.
Записан

while (8==8)
PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #9 : 07-06-2008 08:50 » 

McZim, вот в том-то и фишка что в общем смысле всё кроме асма является частью какого-нибудь API =) ... ксати, скорее свего и асм можно считать часть API процессора.
Записан

Удачного всем кодинга! -=x[PooH]x=-
sss
Специалист

ru
Offline Offline

« Ответ #10 : 07-06-2008 08:57 » 

не знаю как в Windows, а в Linux это делается на раз, два, три Улыбаюсь

Ну не знаю. У меня есть свой OpenDialog, строящий визуальное дерево каталогов на заданную глубину (или до конца). Задача довольно не тривиальная. Если показывать только текущий уровень - то конечно. Помню выходил из положения использованием двух списков и списка - дерева. Я бы мог показать код, но он тесно завязан на мои же библиотеки, представить которые просто не реально.
Записан

while (8==8)
PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #11 : 07-06-2008 09:44 » 

А в чем не привиальность задачи? Просмотриваешь рекурсивно каталоги до определенного уровня и все... в чем проблема то была и зачем списки?
Записан

Удачного всем кодинга! -=x[PooH]x=-
TJ
Гость
« Ответ #12 : 07-06-2008 09:57 » 

НУ да конешн я загнул. апи можно использовать но раскрытие списка и рекурсивный обход папок надо организовать самому.
Записан
PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #13 : 07-06-2008 10:02 » 

ну и в чем проблема?
findfirst + findnext + обычная рекурсия
Записан

Удачного всем кодинга! -=x[PooH]x=-
TJ
Гость
« Ответ #14 : 07-06-2008 12:57 » 

Когда говорят что mtnj легко значит можно бы и продемострировать!
Записан
PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #15 : 07-06-2008 14:49 » 

Задавай вопросы - будут ответы.
Записан

Удачного всем кодинга! -=x[PooH]x=-
TJ
Гость
« Ответ #16 : 07-06-2008 18:29 » 

Код:
//Листинг прожки зацените

 /*
    WinDirectoryListing.cpp
    Windows version of directory traversal
 */

#include <io.h>

#include <string>
#include <vector>

using namespace std;

vector < string > m_vectData;

void listDir(const char * sdir, int count){
    string str, strDir;
    struct _finddata_t c_file;
    long hFile;

    // Find first file in current directory
    str = sdir + (string) "\\*";
    if( (hFile = _findfirst( str.c_str(), &c_file )) == -1L ){
        fprintf(stderr, "Error opening %s!\n", str.c_str());
        return;
    }

    do{
        //skip if find . and ..
        if ((strcmp(c_file.name, ".") == 0 ||  strcmp(c_file.name, "..") == 0)) {
            continue;
        }

        str = "";
        for (int i=0; i<count; i++)
            str += "  ";//indentation for better viewing

        if (c_file.attrib & _A_SUBDIR){
            strDir = sdir + (string) "\\" + (string) c_file.name;
            str += "D: " + strDir;
            m_vectData.push_back(str);
            listDir(strDir.c_str(), count+1);
            continue;
        }
        //join given path and file name
        str += "F: " + (string) sdir + (string) "\\" + (string) c_file.name;
        m_vectData.push_back(str);
    }while(_findnext( hFile, &c_file ) == 0);
   _findclose( hFile );
   return;
}


int main(int argc, char *argv[]){

    listDir(".", 0);

    for (int i=0; i<m_vectData.size(); i++){
        printf("%s\n", m_vectData[i].c_str());
    }
    printf("Press return to exit\n");
    getchar();

    return 0;
}
« Последнее редактирование: 07-06-2008 18:31 от Алексей1153++ » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #17 : 07-06-2008 18:33 » 

ибицца сердце (перестало) ...

плохой листинг, некрасивый Улыбаюсь Препода теперь можно понять.

А работает, кстати ?
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #18 : 07-06-2008 18:41 » 

Код:
        str = "";
        for (int i=0; i<count; i++)
            str += "  ";//indentation for better viewing
а вот это - лучше в начале программы один раз это сделать, чем каждый раз повторять

смысл делать так
Код:
... + (string) sdir +...;

... + (string) "\\" + ...;
какой ?

проще бы

Код:
... +  sdir +...;

... +  "\\" + ...;



Код:
str += "D: " + strDir;
а нужен ли пробед после диска ? Или без разницы ?
Записан

PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #19 : 07-06-2008 18:43 » 

Сам накодил, или скопипиздил откуда-то?
Записан

Удачного всем кодинга! -=x[PooH]x=-
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #20 : 07-06-2008 18:44 » 

Код:
    for (int i=0; i<m_vectData.size(); i++){
        printf("%s\n", m_vectData[i].c_str());
    }
    printf("Press return to exit\n");

не "\n" , а "\r\n" нужно
Записан

Sands
Помогающий

ua
Offline Offline

« Ответ #21 : 07-06-2008 20:40 » 

Алексей1153++, Для вывода на екран, по идее должно хватить "\n" а вот для файла - там по разному, одни "\n" воспринимают нормально, другим "\r\n" подавай
Записан
RXL
Технический
Администратор

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

WWW
« Ответ #22 : 08-06-2008 07:44 » 

Тут для винды и DOS имеет значение, как открывался файл - как двоичный или как текстовый. В случае текстового файла \n заменяется на \r\n при записи и обратно при чтении.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
TJ
Гость
« Ответ #23 : 08-06-2008 17:54 » 

  Как сделать так , что бы при вот такой записи в файл писало не в одну линию, а переходило на новую строку после каждого итого элемента ?
Код:
#include <io.h>
#include <string>
#include <vector>
#include <sys\stat.h>
#include <fcntl.h>
#include <fstream.h>

using namespace std;

vector < string > m_vectData;

void listDir(const char * sdir, int count){
    string str, strDir;
    struct _finddata_t c_file;
    long hFile;

    // Find first file in current directory
    str = sdir + (string) "\\*";
    if( (hFile = _findfirst( str.c_str(), &c_file )) == -1L ){
        fprintf(stderr, "Error opening %s!\n", str.c_str());
        return;
    }

    do{
        //skip if find . and ..
        if ((strcmp(c_file.name, ".") == 0 ||  strcmp(c_file.name, "..") == 0)) {
            continue;
        }

        str = "";
        for (int i=0; i<count; i++)
            str += "  ";//indentation for better viewing

        if (c_file.attrib & _A_SUBDIR){
            strDir = sdir + (string) "\\" + (string) c_file.name;
            str += "D:" + strDir;
            m_vectData.push_back(str);
            listDir(strDir.c_str(), count+1);
            continue;
        }
        //join given path and file name
        str += "F: " + (string) sdir + (string) "\\" + (string) c_file.name;
        m_vectData.push_back(str);
    }while(_findnext( hFile, &c_file ) == 0);
   _findclose( hFile );
   return;
}


int main(int argc, char *argv[]){

   char *path;
   int handle;
 
   
   _fmode = O_BINARY;
   path="c:\\Catolog.txt";
   handle = creat(path, S_IREAD |S_IWRITE);



    listDir(".", 0);

    for (int i=0; i<m_vectData.size(); i++)
     { write(handle, m_vectData[i].c_str(), strlen(m_vectData[i].c_str()));  }
      printf("Press return to exit\n");
   
    getchar();
    return 0;
}
« Последнее редактирование: 08-06-2008 18:51 от Джон » Записан
Oldy
Команда клуба

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

« Ответ #24 : 08-06-2008 18:32 » 

TJ, Пожалуйста, обрамляй свой код тэгами [сode] ... [/сode]
Записан

С уважением, Oldy.
Джон
просто
Администратор

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

« Ответ #25 : 08-06-2008 18:54 » 

TJ, тебе вобще наплевать на людей, которые пытаются тебе помочь? Или как?

Неужели так сложно добавить несколько символов?

Два предупреждения у тебя уже было, расценивай это как третье и последнее.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Sands
Помогающий

ua
Offline Offline

« Ответ #26 : 08-06-2008 19:48 » 

TJ, Вот интересно получается, когда ты выдаеш ошибку о невозможности открытия файла, то ставиш в конце символ возврата строки(проще говоря "\n"), а когда формируеш список файлов, то про етот символ "забываеш". Но поскольку у тебя файл открывается в бинарном виде, то к строке с путем к файлу надо добавлять не "\n" а "\r\n", вроде бы.
Записан
sss
Специалист

ru
Offline Offline

« Ответ #27 : 09-06-2008 01:41 » 

А в чем не привиальность задачи? Просмотриваешь рекурсивно каталоги до определенного уровня и все... в чем проблема то была и зачем списки?

Задача в построении дерева, а не простого вывода в файл.
Классы:
CPtrsList    - двунаправленный список
СTreeList   - список дерево
PTreeNode - указатель на узел дерева
PPtrNode   - указатель на узел двунаправленного списка

Код:
//Метод добавляет в  корень дерева m_SubDirs подкаталоги из пути 
//FromPath на глубину lDepth. lDepth = -1 - весь список

PTreeNode CFoldersTree::EnumFolders( const TCHAR* FromPath,
                                long lDepth) throw ( ELowResources*, ESystemError*, EInfo*)
{

  CPtrsList   list1;
  CPtrsList   list2;
  PPtrsList   psrclist;
  PPtrsList   pdstlist;
  PPtrsList   tmp;
  PTreeNode   pFirstPush;

  //m_SubDirs.Clear();

  // Ложим корневой каталог
  pFirstPush = m_SubDirs.Add( NULL, FromPath, new CFolderItem());
  list1.PushBack( pFirstPush);


  psrclist = &list1;
  pdstlist = &list2;

  while ( lDepth != 0 && psrclist->Count)
  {
    AddNodesSubDirs( pdstlist, psrclist);
    tmp = psrclist;
    psrclist = pdstlist;
    pdstlist = tmp;
    lDepth--;
  }
  return pFirstPush;
}

//Метод перечисляет подкаталоги предыдущих добавленных узлов дерева, добавляет их к дереву и
//сохраняет список вновь добавленных во втором списке, который станет источником для нового
//перечисления
void CFoldersTree::AddNodesSubDirs( PPtrsList pDstList, PPtrsList pSrcList) throw ( ELowResources*, ESystemError*, EInfo*)
{
  WIN32_FIND_DATA   FindData;
  CStr              path;
  CStr              ExtPath;

  PPtrNode          pCursor;
  PTreeNode         pRoot;

  PFolderItem       pFolderItem;
  HANDLE            hSearch;

  pDstList->Clear();
  pCursor = pSrcList->First;

  while ( pCursor)
  {
    pRoot = (PTreeNode) pCursor->Data;
    GetNodePath( pRoot, &path); //Возвращает полный путь этого узла

    path += TEXT("*.*");
    FileExtentPath( path.t_str(), path); //Добавляет к пути TEXT("\\\\?\\") или TEXT("\\\\?\\UNC")

    hSearch = ::FindFirstFileExW( path.t_str(), FindExInfoStandard, &FindData, FindExSearchNameMatch, NULL, 0);

    if ( hSearch == INVALID_HANDLE_VALUE)
    {
      DWORD dwError = ::GetLastError();
      if ( m_bIgnoreErrors == false || dwError != ERROR_FILE_NOT_FOUND)
          throw new __ESystemError( dwError);
    }
    else
    {
      try
      {
        do
        {
          if ( IsDirectory( &FindData))
              pDstList->PushBack( m_SubDirs.AddSub( pRoot, FindData.cFileName, new CFolderItem()));
        } while ( ::FindNextFile( hSearch, &FindData));
      }
      catch( EExcept*)
      {
        ::FindClose( hSearch);
        throw;
      }
      ::FindClose( hSearch);
    }
    pFolderItem = (PFolderItem) pRoot->Data;
    pFolderItem->Enumerated = true;               
    pCursor = pCursor->Next;
  } //while pCursor
}

Могу выложить приложение которое использует класс CFoldersTree. Перечисляет даже корни DFS.

Еще хотел добавить, что рекурсия может получиться ой какой глубокой...
« Последнее редактирование: 09-06-2008 02:22 от sss » Записан

while (8==8)
Алексей++
глобальный и пушистый
Глобальный модератор

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


« Ответ #28 : 09-06-2008 03:37 » 

Oldy, с появлением! Улыбаюсь
Записан

PooH
Глобальный модератор

ru
Offline Offline
Пол: Мужской
... и можно без хлеба!


« Ответ #29 : 09-06-2008 05:43 » 

sss, я из кода так и не понял зачем отдельные списки =( их же вроде можно в само дерево воткнуть?
что-то вроде:
Код: (Text)
NODE:
Pointer Parent_Node_Prt
ArrayOfNODEPrt ChildNodes //для удобства прохода вглубь дерева
x_Data  Data //данные узла, например, название каталога
ну в общем в каждом узле хранить данные, инфу о предке и о наследниках
« Последнее редактирование: 09-06-2008 05:46 от PooH » Записан

Удачного всем кодинга! -=x[PooH]x=-
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines