利用 <filesystem> 库;视觉工作室
Utilizing the <filesystem> library; visualStudios
我会缩短它的长度。我试图了解文件系统库,但我能找到的信息很少。我设法让它编译并很好地理解 filesystem::path 类型变量,但似乎不明白如何让 filesystem::directory_iterator 正常工作。我不确定我是否将它用于非设计目的。所以这就是我正在尝试做的事情:
我想创建一个程序来打开指定文件夹中的每个文本文件。为此,我需要获取文件夹名称和路径,但我希望程序能够自行动态获取此信息,因此如果我添加或删除 textFiles,它将具有正常运行的逻辑。
我能够创建一个 directory_iterator 变量,它设法保存第一个文件,只需给它这样的目录:
const char address[]{ "C:\Users\c-jr8\ProgramBranch\PersonalPlatform\log extruder\logs" };
fs::directory_iterator myIterator(address);
测试文件夹中的代码时,我有四个名为 "attempt 1" 到 "attempt 4" 的文本文件。阅读信息时:
https://docs.microsoft.com/en-us/cpp/standard-library/directory-iterator-class?view=vs-2019#op_star
它提到了两个将迭代器中的路径对象移动到下一个文件的函数。第一个是 increment(),这是迭代文件的预期方法,以及 operation++()。
现在 increment() 无法为我工作,因为它需要一个 erro_code 类型的变量,而且我无法找到有关如何使用 filesystem_errorcode 变量,或者它应该被使用。 operation++() 工作得很好,并为我提供了每个文件的路径,但我在管理代码以检测 operate++() 函数何时导致没有其他文件时遇到了问题。一旦遍历每个文件,当它继续移动到下一个文件时,它就会崩溃。这是那段代码:
string tempString;
for (int i = 0; i < 5; i++) { //Here the limiting is 5 so it'll iterate onces more than the numbers of files unpurpose to see how it responses.
tempString = myIterator.operator*().path().generic_string();
ifstream tempFile(tempString);
if (!tempFile.is_open()) {
cout << "Looking at file: " << i + 1 << "; failed to open." << endl << endl;
cin.get();
return 0;
}
{
//do things with file...
}
tempFile.close();
myIterator.operator++();
}
我想要的是找到一种方法在迭代器离开最终文件后停止 for 循环。
任何有关文件系统库如何工作的信息都将不胜感激。
您应该将 myIterator
与默认构建的 directory_iterator
进行比较,以检查是否已处理最后一个文件。您还可以使用更简单的形式来访问运算符(如以下代码所示):
string tempString;
// loop until myIterator == fs::directory_iterator{}
for(size_t i = 1; myIterator != fs::directory_iterator{}; ++i) {
// access path() through the iterators operator->
tempString = myIterator->path().generic_string();
ifstream tempFile(tempString);
if(!tempFile.is_open()) {
cout << "Looking at file: " << i << "; failed to open." << endl << endl;
cin.get();
return 0;
}
{
std::cout << tempString << " opened\n";
}
// tempFile.close(); // closes automatically when it goes out of scope
// simpler form to use myIterator.operator++():
++myIterator;
}
一种更简单的方法是使用基于范围的 for 循环:
for(const fs::directory_entry& dirent : fs::directory_iterator(address)) {
const fs::path& path = dirent.path();
ifstream tempFile(path);
if(!tempFile) {
cout << "Looking at file: " << path << "; failed to open.\n\n";
cin.get();
return 0;
}
std::cout << path << " opened\n";
}
std::directory_iterator
是一个经典的迭代器,它允许在范围内进行迭代,这些迭代器通常由一对迭代器指定,一个表示序列的开始,另一个表示尾后迭代器。
一些迭代器类型,如提供流访问的迭代器类型,在内存中没有实际的结束位置。类似的情况适用于目录迭代器。在这种情况下,惯用的方法是使用默认构造的迭代器对象作为结束指示器。
话虽如此,您可以将循环重写为:
for (fs::directory_iterator myIterator(address), end{}; myIterator != end; ++myIterator) {
或者,您可以使用基于范围的 for 循环:
for (auto& p : fs::directory_iterator(address)) {
tempString = p.path().generic_string();
// ...
此外,请注意迭代器的 接口 应该像指针一样 look/behave,因此它使用运算符重载以实现简洁的语法。所以而不是:
myIterator.operator++();
你应该使用:
++myIterator;
同样,代替:
myIterator.operator*().path().generic_string();
请使用:
(*myIterator).path().generic_string();
或:
myIterator->path().generic_string();
我会缩短它的长度。我试图了解文件系统库,但我能找到的信息很少。我设法让它编译并很好地理解 filesystem::path 类型变量,但似乎不明白如何让 filesystem::directory_iterator 正常工作。我不确定我是否将它用于非设计目的。所以这就是我正在尝试做的事情:
我想创建一个程序来打开指定文件夹中的每个文本文件。为此,我需要获取文件夹名称和路径,但我希望程序能够自行动态获取此信息,因此如果我添加或删除 textFiles,它将具有正常运行的逻辑。
我能够创建一个 directory_iterator 变量,它设法保存第一个文件,只需给它这样的目录:
const char address[]{ "C:\Users\c-jr8\ProgramBranch\PersonalPlatform\log extruder\logs" };
fs::directory_iterator myIterator(address);
测试文件夹中的代码时,我有四个名为 "attempt 1" 到 "attempt 4" 的文本文件。阅读信息时:
https://docs.microsoft.com/en-us/cpp/standard-library/directory-iterator-class?view=vs-2019#op_star
它提到了两个将迭代器中的路径对象移动到下一个文件的函数。第一个是 increment(),这是迭代文件的预期方法,以及 operation++()。
现在 increment() 无法为我工作,因为它需要一个 erro_code 类型的变量,而且我无法找到有关如何使用 filesystem_errorcode 变量,或者它应该被使用。 operation++() 工作得很好,并为我提供了每个文件的路径,但我在管理代码以检测 operate++() 函数何时导致没有其他文件时遇到了问题。一旦遍历每个文件,当它继续移动到下一个文件时,它就会崩溃。这是那段代码:
string tempString;
for (int i = 0; i < 5; i++) { //Here the limiting is 5 so it'll iterate onces more than the numbers of files unpurpose to see how it responses.
tempString = myIterator.operator*().path().generic_string();
ifstream tempFile(tempString);
if (!tempFile.is_open()) {
cout << "Looking at file: " << i + 1 << "; failed to open." << endl << endl;
cin.get();
return 0;
}
{
//do things with file...
}
tempFile.close();
myIterator.operator++();
}
我想要的是找到一种方法在迭代器离开最终文件后停止 for 循环。
任何有关文件系统库如何工作的信息都将不胜感激。
您应该将 myIterator
与默认构建的 directory_iterator
进行比较,以检查是否已处理最后一个文件。您还可以使用更简单的形式来访问运算符(如以下代码所示):
string tempString;
// loop until myIterator == fs::directory_iterator{}
for(size_t i = 1; myIterator != fs::directory_iterator{}; ++i) {
// access path() through the iterators operator->
tempString = myIterator->path().generic_string();
ifstream tempFile(tempString);
if(!tempFile.is_open()) {
cout << "Looking at file: " << i << "; failed to open." << endl << endl;
cin.get();
return 0;
}
{
std::cout << tempString << " opened\n";
}
// tempFile.close(); // closes automatically when it goes out of scope
// simpler form to use myIterator.operator++():
++myIterator;
}
一种更简单的方法是使用基于范围的 for 循环:
for(const fs::directory_entry& dirent : fs::directory_iterator(address)) {
const fs::path& path = dirent.path();
ifstream tempFile(path);
if(!tempFile) {
cout << "Looking at file: " << path << "; failed to open.\n\n";
cin.get();
return 0;
}
std::cout << path << " opened\n";
}
std::directory_iterator
是一个经典的迭代器,它允许在范围内进行迭代,这些迭代器通常由一对迭代器指定,一个表示序列的开始,另一个表示尾后迭代器。
一些迭代器类型,如提供流访问的迭代器类型,在内存中没有实际的结束位置。类似的情况适用于目录迭代器。在这种情况下,惯用的方法是使用默认构造的迭代器对象作为结束指示器。
话虽如此,您可以将循环重写为:
for (fs::directory_iterator myIterator(address), end{}; myIterator != end; ++myIterator) {
或者,您可以使用基于范围的 for 循环:
for (auto& p : fs::directory_iterator(address)) {
tempString = p.path().generic_string();
// ...
此外,请注意迭代器的 接口 应该像指针一样 look/behave,因此它使用运算符重载以实现简洁的语法。所以而不是:
myIterator.operator++();
你应该使用:
++myIterator;
同样,代替:
myIterator.operator*().path().generic_string();
请使用:
(*myIterator).path().generic_string();
或:
myIterator->path().generic_string();