Как я могу получить список файлов и каталогов пути, используя C ++? - PullRequest
0 голосов
/ 14 марта 2011

Я использую класс каталога для получения этой информации, но не могу присвоить эти данные члену моего собственного класса. Я делаю проект ООП. Кроме того, я хочу использовать концепцию динамизма (сдерживания). Я создал два класса, mydirectory и myfiles, как показано ниже:

class files
{
    string fname[25];
public:
    files()
    {
      fname=NULL;
    }

};

class directory
{ private:
    directory *d;
    string *dname[25];   //* to show there may be a subdirectory,there may be not.
    files *ff[25];       // data member string *fname[25];
int numd,numf;
public:
    directory()
    {
    numd=0;numf=0;
    }

Теперь, когда я хочу использовать устав:

 Directory::GetDirectories("D:\\"); 

как я могу назначить имена каталогов для "dname" класса каталогов.

Я не хочу включать стороннее программное обеспечение.

также мне нужна помощь по теме: как файл (doc file / pdf / txt / pwt и т. Д.) Можно открыть из кода c ++ вне консоли? Я очень взволнован. Помогите мне, пожалуйста. заранее спасибо.

Я новичок в c ++, поэтому, пожалуйста, прости, если есть какие-либо ошибки в обработке указателей, так как я делаю это сдерживание впервые. Мне также нужно кое-что почитать.

Ответы [ 4 ]

1 голос
/ 18 апреля 2011

Поскольку это помечено как домашнее задание, мы не будем сильно вам помогать, давая правильный ответ.Но я укажу вам правильное направление.

Вы указали, что делаете это в Visual C ++.Без использования сторонних библиотек, но только с тем, что встроено, вам потребуется доступ к Win32 API.

FindFirstFile () и FindNextFile () - это то, что вам нужно.

Вы будетеСначала вызовите FindFirstFile, чтобы получить дескриптор каталога.Параметр - это D: \, который вы передаете в свой класс.

Затем вызовите FindNextFile в цикле while.

Например, основной принцип использования этих API:

HANDLE h = FindFirstFile("D:\\");
WIN32_FIND_DATA data;
while (FindNextFile(h, &data))
{
   // Check if it's a directory or not
   if (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY){
     // Add to dname
   }
}

Подумайте об использовании std :: vector для вашего dname вместо строки *, потому что вы застряли с 25 записями.Используя вектор, он будет расти для вас.

1 голос
/ 14 марта 2011

Самый простой способ сделать это в C ++ - это использовать boost :: filesystem.

Пока путь является каталогом, вы можете перебирать его, используя директорию directory_iterator или recursive_directory_iterator.

например:

boost::filesystem::path dirname( "D:\\" );

std::vector<boost::filesystem::path> topLevel( directory_iterator(dirName), 
      directory_iterator() );

std::vector<boost::filesystem::path> wholeDrive( 
       recursive_directory_iterator(dirName), recursive_directory_iterator() );
0 голосов
/ 18 апреля 2011

Наконец, я завершил короткий проект. Чтобы получить список файлов и подкаталогов, я использовал .NET Framework namespace "System". У него есть классы типа "FileInfo" и "DirectoryInfo" (оба принадлежат System::IO) которые выполняют вышеуказанную требуемую задачу. Но здесь все, что связано со строкой, имеет значение System::String, а не std::string. Чтобы преобразовать System::String в std::string, я использовал следующий код (я получил код этого преобразованияс форума, и все работало нормально без ошибок):

string Str2str(String ^a)
{
array<Byte> ^chars = System::Text::Encoding::ASCII->GetBytes(a);
pin_ptr<Byte> charsPointer = &(chars[0]);
char *nativeCharsPointer = reinterpret_cast<char *>(static_cast<unsigned char *>(charsPointer));
string native(nativeCharsPointer, chars->Length);
return native;
}

Вот краткий код для получения списка подкаталогов с диска (D: диск будет искать):

 #include<iostream>
        #using<mscorlib.dll>
        using namespace strd;        
        using namespace System;
        using namespace System::IO;


int main()
    {int count=50;
string name[count];//to hold directories names
string b;
int s=0;
DirectoryInfo^ di = gcnew DirectoryInfo("d:\\");
if(di->Exists)
{array<DirectoryInfo^>^diArr = di->GetDirectories();
Collections::IEnumerator^ myEnum = diArr->GetEnumerator();
while ( myEnum->MoveNext() )
{DirectoryInfo^ dri = safe_cast<DirectoryInfo^>(myEnum->Current);


      String ^a=(dri->Name->ToString());
      int n=b.size();
      b=Str2str(a); `// code given in the starting`
      if (s<count)
      {name[s]=b;
      s++;}

}

Это включает в себя знания об управляемом C ++.Посетите их:

Руководство по программированию .NET

C ++: самый мощный язык программирования для .NET Framework

Я скомпилировалэто на Visual Studio 2008. Буду очень признателен, если вы оцените мои усилия. Дополнительные предложения приветствуются.

0 голосов
/ 14 марта 2011

Как сказал CashCow, boost :: filesystem

Как правило, в C ++ для таких примеров указатель не требуется.Вот несколько ошибок, которые вы должны исправить:

string fname[25];

Это объявляет массив из 25 строк.Вы, вероятно, хотели строку из 25 символов?Ну, в std :: string вам не нужно заботиться о длине.std :: string fname;достаточно

std::string file_name;
file_name = "baz.txt";

fname=NULL;

Если fname является строкой, то это не указатель.Таким образом, вы не можете присвоить ему значение NULL.Std :: string по умолчанию инициализируется как пустая строка.Вы можете опустить весь конструктор.

string *dname[25]

Полагаю, вы хотели иметь массив строк.Просто используйте:

std::vector<std::string> dnames;
dnames.push_back("foo");
dnames.push_back("bar"); // dnames now contains {"foo","bar"}

И у вас будет динамически изменяемый вектор строк.

Смотрите: указатель не нужен.Не нужно никаких новых

...