[英]How to list all CSV files in a Windows Directory using C++?
I'm a bit new to C++ and I've to list all CSV files in a Windows Directory, I've googled and I found a lot of ways to list all files in a directory and I came up with the following solution: 我对C ++有点陌生,我必须在Windows目录中列出所有CSV文件,我已经用Google搜索过,发现了很多方法可以列出目录中的所有文件,并且提出了以下解决方案:
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;
}
It is using the dirent.h for Windows (I'm using VS2013) but the problems are: - Is it correct to set isFile = 32768? 它正在Windows上使用dirent.h(我正在使用VS2013),但问题是:-设置isFile = 32768是否正确? Will it always work on Windows?
它将始终在Windows上运行吗? - How to know if the file is a CSV file?
-如何知道该文件是否为CSV文件?
Another thing, I've tried to use windows.h / FindNextFile but it didn't work. 另一件事,我尝试使用windows.h / FindNextFile,但是没有用。 Is it better to use FindNextFile or the above solution?
使用FindNextFile还是上述解决方案更好?
I guess FindNextFile would be easier to list only the CSV File, but I don't know how to do it. 我想FindNextFile仅列出CSV文件会更容易,但是我不知道该怎么做。
My exit should be a string because it is an input of a function that reads the CSV Files. 我的出口应该是一个字符串,因为它是读取CSV文件的函数的输入。
Tks guys. Tks的家伙。
PS: I cant use boost... PS:我不能使用升压...
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");
}
If you want to use FindNextFile, msdn has an example for enumerating all fiels in a directory here which you can adapt. 如果要使用FindNextFile,则msdn有一个示例,可以列举一个目录中的所有文件,您可以在其中进行调整。
EDIT: To expand on the windows API method: 编辑:在Windows API方法上展开:
argv
is of type TCHAR*
, meaning either char*
or wchar_t*
depending on #ifdef UNICODE
. argv
类型为TCHAR*
,表示char*
或wchar_t*
取决于#ifdef UNICODE
。 It's a type used by all Windows API calls which take a string parameter. 所有带有字符串参数的Windows API调用都使用此类型。 To create a
TCHAR
literal you can use TEXT("text")
. 要创建
TCHAR
文字,您可以使用TEXT("text")
。 To create a wchar_t
literal you can use L"text"
. 要创建
wchar_t
文字,可以使用L"text"
。 If you do not want to use TCHAR semantics you can redefine main
to be of type int main(int argc, char* argv)
, or int wmain(int argc, wchar_t* arv)
. 如果您不想使用TCHAR语义,则可以将
main
重新定义为int main(int argc, char* argv)
或int wmain(int argc, wchar_t* arv)
。 Converting between the two types involves dealing with unicode and code pages, which you should probably use a 3rd party library for. 两种类型之间的转换涉及处理unicode和代码页,您可能应该使用第3方库。
Converting from ASCII ( std::string
or char*
with char points in 0-127) to unicode( std::wstring
or wchar_t*
is a simple matter of creating a std::wstring(std::string.cbegin(), std::string.cend())
. 从ASCII(
std::string
或char*
,char点在0-127之间)转换为unicode( std::wstring
或wchar_t*
是创建std::wstring(std::string.cbegin(), std::string.cend())
的简单问题std::wstring(std::string.cbegin(), std::string.cend())
。
Here is a code example demonstrating use of WinAPI functions to list files in a directory: 这是一个代码示例,演示了如何使用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"));
}
If you want to simplify it, you can make your application either locked in unicode or completely ignorant of unicode by removing all T (TCHAR, TEXT(), the newly-defined tstring, tcout, tcerr) variants and using purely wide or non-wide types (ie. char*, string, simple literals, cout OR wchar_t*, wstring, L"" literals, wcout). 如果您想简化它,可以通过删除所有T(TCHAR,TEXT(),新定义的tstring,tcout,tcerr)变体并使用纯宽或非宽幅格式,使应用程序锁定在unicode中或完全不了解unicode。宽类型(即char *,字符串,简单文字,cout或wchar_t *,wstring,L“”文字,wcout)。 If you do this, you need to use the specialied functions of WINAPI functions (ie FindFirstFileA for non-wide and FindFirstFileW for wide)
如果执行此操作,则需要使用WINAPI函数的专用函数(即,对于非宽范围使用FindFirstFileA,对于宽范围使用FindFirstFileW)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.