Как я могу получить список файлов и каталогов пути, используя C++?
Я использую класс каталога для получения этой информации, но не могу присвоить эти данные члену моего собственного класса. Я делаю проект ООП. Кроме того, я хочу использовать концепцию динамизма (сдерживания). Я создал два класса, 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 ответа
Наконец, я завершил короткий проект. Чтобы получить список файлов и подкаталогов, я использовал .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. Буду очень признателен, если вы оцените мои усилия. Дальнейшие предложения приветствуются.
Самый простой способ сделать это в 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() );
Поскольку это помечено как домашнее задание, мы не будем сильно помогать вам, давая правильный ответ. Но я укажу вам в правильном направлении.
Вы указали, что делаете это под 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 вместо string*, потому что вы застряли с 25 записями. Используя вектор, он будет расти для вас.
Как сказал 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"}
И у вас будет динамически изменяемый вектор строк.
Смотрите: не нужно никаких указателей. Не нужно никаких новых