从文件夹中读取文件并将其保存到字符串向量中
Read files from a folder and save it to vector of strings
我正在尝试从文件夹中读取文本文件,并将名称保存到字符串向量中。这是我的代码。我可以编译并运行它,但它不会将我的文件保存到向量中。
int main(){
Data Dataset;
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
// Find the first file in the directory.
hFind = FindFirstFile(LPCTSTR("C:\Users\bla\Desktop\c++\data\*"), &FindFileData);
if (hFind == INVALID_HANDLE_VALUE) {
cout<<"ERROR"<<endl;
}
else{
while (FindNextFile(hFind, &FindFileData) != 0) {
if(FindFileData.cFileName=="*.txt")
{
Dataset.name.push_back(FindFileData.cFileName);
}
cout<<FindFileData.cFileName<<endl;
}
FindClose(hFind);
}
for(int i=0; i<Dataset.name.size(); i++){
cout<<Dataset.name[i]<<endl;
}
}
我们非常感谢您提供的任何帮助。
一个问题是:
FindFileData.cFileName=="*.txt"
首先,这不会比较字符串。它比较指针值。如果要比较字符串,请使用_tcscmp
:
if ( _tcscmp(FindFileData.cFileName, _T("*.txt")) == 0 )
其次,这是错误的:
hFind = FindFirstFile(LPCTSTR("C:\Users\bla\Desktop\c++\data\*"), &FindFileData);
您正试图将非宽字符串强制转换为宽字符串或非宽字符串,这取决于项目的字符集构建类型(我假设您使用的是Visual Studio,但它与您的C++工具有关)。
底线是never强制转换字符串类型以适应参数类型。铸造字符串是而不是将字符串从一种类型转换为另一种类型。您应该编写从不需要强制转换字符串的代码——如果最终强制转换字符串,那么代码就是错误的。
如果删除强制转换,你总是可以判断出有什么不好或需要仔细检查,通过删除强制转换编译器会抛出一个错误,告诉你类型不匹配(这不仅适用于字符串,也适用于你认为需要强制转换的任何类型)。
对于此实例,修复方法是使用tchar.h
中定义的_T
或TEXT
宏,该宏为您提供适当的字符串文字类型。
hFind = FindFirstFile(_T("C:\Users\bla\Desktop\c++\data\*"), &FindFileData);
最后,您真的将文件名与"*.txt"进行比较吗?Windows系统中的任何文件都不能用星号命名。
您的代码有很多问题。TCHAR
数据处理不正确。FindFirstFile
数据的循环不正确(您正在跳过找到的第一个文件)。文件扩展名的比较无效。
请尝试类似的方法,特别是因为您使用的是std::string
和std::cout
,这意味着您也使用了基于ANSI的Win32 API(否则您显示的代码将无法编译):
struct Data
{
std::vector<std::string> name;
unsigned int vehicle;
unsigned int dim;
int maxQ;
};
int main()
{
Data Dataset;
WIN32_FIND_DATAA FindFileData;
HANDLE hFind;
DWORD dwErr;
// Find the first file in the directory.
hFind = FindFirstFileA("C:\Users\bla\Desktop\c++\data\*.txt", &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
dwErr = GetLastError();
if (dwErr != ERROR_FILE_NOT_FOUND)
std::cerr << "ERROR: " << dwErr << std::endl;
}
else
{
do
{
if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
{
Dataset.name.push_back(FindFileData.cFileName);
//std::cout << FindFileData.cFileName << std::endl;
}
}
while (FindNextFileA(hFind, &FindFileData));
dwErr = GetLastError();
if (dwErr != ERROR_NO_MORE_FILES)
std::cerr << "ERROR: " << dwErr << std::endl;
FindClose(hFind);
}
for(int i = 0; i < Dataset.name.size(); i++)
{
std::cout << Dataset.name[i] << std::endl;
}
return 0;
}
否则,您应该切换到std::wstring
和std::wcout
,以及基于Unicode的API:
struct Data
{
std::vector<std::wstring> name;
unsigned int vehicle;
unsigned int dim;
int maxQ;
};
int main()
{
Data Dataset;
WIN32_FIND_DATAW FindFileData;
HANDLE hFind;
DWORD dwErr;
// Find the first file in the directory.
hFind = FindFirstFileW(L"C:\Users\bla\Desktop\c++\data\*.txt", &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
dwErr = GetLastError();
if (dwErr != ERROR_FILE_NOT_FOUND)
std::wcerr << L"ERROR: " << dwErr << std::endl;
}
else
{
do
{
if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
{
Dataset.name.push_back(FindFileData.cFileName);
//std::wcout << FindFileData.cFileName << std::endl;
}
}
while (FindNextFileW(hFind, &FindFileData));
dwErr = GetLastError();
if (dwErr != ERROR_NO_MORE_FILES)
std::wcerr << L"ERROR: " << dwErr << std::endl;
FindClose(hFind);
}
for(int i = 0; i < Dataset.name.size(); i++)
{
std::wcout << Dataset.name[i] << std::endl;
}
return 0;
}
无论出于何种原因,如果您必须坚持使用TCHAR
数据,您也可以这样做:
typedef std::basic_string<TCHAR> tstring;
struct Data
{
std::vector<tstring> name;
unsigned int vehicle;
unsigned int dim;
int maxQ;
};
int main()
{
Data Dataset;
WIN32_FIND_DATA FindFileData;
HANDLE hFind;
DWORD dwErr;
#ifdef UNICODE
std::wostream &std_out = std::wcout;
std::wostream &std_err = std::wcerr;
#else
std::ostream &std_out = std::cout;
std::ostream &std_err = std::cerr;
// Find the first file in the directory.
hFind = FindFirstFile(TEXT("C:\Users\bla\Desktop\c++\data\*.txt"), &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
dwErr = GetLastError();
if (dwErr != ERROR_FILE_NOT_FOUND)
std_err << TEXT("ERROR: ") << dwErr << std::endl;
}
else
{
do
{
if ((FindFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
{
Dataset.name.push_back(FindFileData.cFileName);
//std_out << FindFileData.cFileName << std::endl;
}
}
while (FindNextFile(hFind, &FindFileData));
dwErr = GetLastError();
if (dwErr != ERROR_NO_MORE_FILES)
std_err << TEXT("ERROR: ") << dwErr << std::endl;
FindClose(hFind);
}
for(int i = 0; i < Dataset.name.size(); i++)
{
std_out << Dataset.name[i] << std::endl;
}
return 0;
}
我认为问题的主要原因是这行代码
Dataset.name.push_back(FindFileData.cFileName);
在这一行中,您将WIN32_FIND_DATA::cFileName
属性直接推回到vector,并且由于vector在下次调用FindNextFile
时保留该属性的地址,它将覆盖以前的值。出于这个原因,最好分配新的缓冲区并将WIN32_FIND_DATA::cFileName
复制到这个新缓冲区,然后将这个新缓冲推送到向量。
- 将字符指针十六进制转换为字符串并保存在文本文件C++中
- C++.我想将更改后的特定字符行保存在字符串中
- 保存名称或字符串
- C++ 将地址保存为字符串的向量转换为新的向量
- C++读取大文件并将其保存到字符串中,然后删除特定的随机单词
- C++以尽可能快的速度逐行将字符串保存到文件中
- 如何在c++中将字符串中的所有数字保存到多维数组中
- C++我应该用什么来保存格式化为字符串变量(如sprintf())的文件
- 使用 ctime 保存新时间点会覆盖旧字符串?
- 如何将 std::string 作为构造函数参数传递,并将其保存的 C 字符串存储在 void 指针中?
- 获取线未将所有字符保存到字符串
- 获取线函数未定义错误。无法在字符串中保存可验证的内容
- 如何将字符串保存在最长的常见子序列递归算法中
- 如果我不将预先编写的字符串保存到变量,它还在内存中吗?
- 声明变量以保存字符串列表时的内存分配
- 为什么 boost::any 不保存字符串文字
- 如何保存字符串并按顺序读取/写入它们
- 如何从编辑框中保存字符串以及如何使用复选框禁用编辑框
- 如何在枚举中保存字符串
- 使用next_permutation函数后如何保存字符串/整数