Как перечислить все файлы CSV в каталоге Windows, используя C ++?

Я немного новичок в C ++, и я должен перечислить все файлы CSV в каталоге Windows,
Я гуглил и нашел много способов перечислить все файлы в каталоге и
Я придумал следующее решение:

int listFiles(string addDir, vector<string> &list) {
DIR *dir = 0;
struct dirent *entrada = 0;
int isFile = 32768;

dir = opendir(addDir.c_str());

if (dir == 0) {
cerr << "Could not open the directory." << endl;
exit(1);
}

while (entrada = readdir(dir))
if (entrada->d_type == isFile)
{
list.push_back(entrada->d_name);
cout << entrada->d_name << endl;
}
closedir(dir);

return 0;
}

Он использует dirent.h для Windows (я использую VS2013), но проблемы:
Правильно установить isFile = 32768? Будет ли это всегда работать на Windows?
— Как узнать, является ли файл CSV-файл?

Другое дело, я пытался использовать windows.h / FindNextFile, но это не сработало.
Лучше использовать FindNextFile или вышеуказанное решение?

Я думаю, FindNextFile было бы проще перечислить только файл CSV, но я не знаю, как это сделать.

Мой выход должен быть строкой, потому что это ввод функции, которая читает файлы CSV.

Ткс, ребята.

PS: я не могу использовать повышение …

1

Решение

int listFiles(const string& addDir, vector<string> &list, const std::string& _ext) {
DIR *dir = 0;
struct dirent *entrada = 0;
int isFile = 32768;
std::string ext("." + _ext);
for (string::size_type i = 0; i < ext.length(); ++i)
ext[i] = tolower(ext[i]);

dir = opendir(addDir.c_str());

if (dir == 0) {
cerr << "Could not open the directory." << endl;
exit(1);
}

while (entrada = readdir(dir))
if (entrada->d_type == isFile)
{
const char *name = entrada->d_name;
size_t len = strlen(entrada->d_name);
if (len >= ext.length()) {
std::string fext(name + len - ext.length());
for (string::size_type i = 0; i < fext.length(); ++i)
fext[i] = tolower(fext[i]);

if (fext == ext) {
list.push_back(entrada->d_name);
cout << entrada->d_name << endl;
}
}
}
closedir(dir);

return 0;
}
int main()
{

vector<string> flist;
listFiles("c:\\", flist, "csv");
system("PAUSE");
}

Если вы хотите использовать FindNextFile, у msdn есть пример для перечисления всех полей в каталоге Вот который вы можете адаптировать.


РЕДАКТИРОВАТЬ: Чтобы расширить на метод Windows API:

argv имеет тип TCHAR*, что означает либо char* или же wchar_t* в зависимости от #ifdef UNICODE, Этот тип используется всеми вызовами Windows API, которые принимают строковый параметр. Чтобы создать TCHAR буквально вы можете использовать TEXT("text"), Чтобы создать wchar_t буквально вы можете использовать L"text", Если вы не хотите использовать семантику TCHAR, вы можете переопределить main быть типом int main(int argc, char* argv), или же int wmain(int argc, wchar_t* arv), Преобразование между этими двумя типами включает в себя работу с юникодом и кодовыми страницами, для которых вам, вероятно, следует использовать стороннюю библиотеку.

Преобразование из ASCII (std::string или же char* с символами в 0-127) в Unicode (std::wstring или же wchar_t* это простой вопрос создания std::wstring(std::string.cbegin(), std::string.cend()),

Вот пример кода, демонстрирующий использование функций WinAPI для вывода списка файлов в каталоге:

#include <windows.h>
#incldue <string>
#include <iostream>

#ifdef UNICODE
typedef std::wstring tstring;
#else
typedef std::string tstring;
#endif
#ifdef UNICODE
std::wostream& tcout = std::wcout;
std::wostream& tcerr = std::wcerr;
#else
std::ostream& tcout = std::cout;
std::ostream& tcerr = std::cerr;
#endif

int listFiles(const tstring& directory, std::vector<tstring> &list, const tstring& extension)
{
using std::endl;
WIN32_FIND_DATA file;
HANDLE hListing;
int error;

tstring query;
if (directory.length() > MAX_PATH - 2 - extension.length())
tcerr << "directory name too long" << endl;
query = directory + TEXT("*.") + extension;

hListing = FindFirstFile(query.c_str(), &file);
if (hListing == INVALID_HANDLE_VALUE) {
error = GetLastError();
if (error == ERROR_FILE_NOT_FOUND)
tcout << "no ." << extension << " files found in directory " << directory << endl;
return error;
}

do
{
if ((file.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
{
tcout << file.cFileName << endl;
list.push_back(file.cFileName);
}
} while (FindNextFile(hListing, &file) != 0);

error = GetLastError();
if (error == ERROR_NO_MORE_FILES)
error = 0;

FindClose(hListing);
return error;
}
int _tmain(int argc, TCHAR* argv[])
{
std::vector<tstring> files;
listFiles(TEXT("C:\\"), files, TEXT("sys"));
if (argc > 1)
listFiles(argv[1], files, TEXT("csv"));
}

Если вы хотите упростить его, вы можете сделать ваше приложение заблокированным в юникоде или полностью игнорировать юникод, удалив все варианты T (TCHAR, TEXT (), недавно определенные варианты tstring, tcout, tcerr) и используя чисто широкие или не широкие типы (т. е. char *, string, простые литералы, cout ИЛИ wchar_t *, wstring, L «» литералы, wcout).
Если вы делаете это, вам нужно использовать специализированные функции функций WINAPI (то есть FindFirstFileA для неширокого и FindFirstFileW для широкого)

1

Другие решения


По вопросам рекламы [email protected]