【发布时间】:2022-01-19 21:47:16
【问题描述】:
我想编写一个程序来读取给定目录中的文件,为文件的扩展名创建文件夹,然后将文件移动到新文件夹中。
我对 C++ 还很陌生,因为我之前所做的只是玩弄诸如方法和类之类的小东西,所以我真的不知道出了什么问题。
程序第一次在文件夹上运行时,它会正确创建所需的文件夹,但不会移动文件。
第二次运行时,没有任何变化,但它在当前文件夹的原始目录中创建了一组嵌套文件夹。我的意思是,如果文件夹目录是A:/b/c/d/,它开始创建b 的文件夹。我已经尝试在另一个文件夹上进行测试,它确实正确地制作了文件夹,但没有移动文件。
我添加了 cmets 以防代码难以阅读。我特意将制作文件夹和移动文件的逻辑设置为单独的方法,以便于编辑。我应该注意,即使文件没有被移动,rename 函数确实返回 0,表明它被移动了。
至于库,我计划在一切正常后清理它们。
/*
main.cpp
File Creator and Sorter
Made in almost 24 hours
First personal c++ project
This program takes an input from the user in the form of /Users/.../.../.../... , ... being a folder location.
It then goes through the files in the folder, finds any extensions, creates folders for those extensions, and moves the files there.
There is a chance for a few files to be located in the folder that don't have a file type. For those files I plan to implement a
miscallaneos folder and move them there. Do not use this program unless you confirmed you want to sort everything in the folder.
The reason being this will not leave any file alone and can mess up and set ups.
Created by yared yohannes on 12/15/21.
*/
// libraries idk what is needed and not so needs to be cleaned up
#include <dirent.h>
#include <cstdio>
#include <fstream>
#include <iostream>
// namespaces dont mess with cause filesystem was giving problems, im new.
using namespace std;
namespace fs = filesystem;
// turns the files in the string array into an extension section, and if it is
// not an extension(from noticing the .) removes it. the reason for the removing
// of unknown files is cause create_directory has an error on weird filenames.
void extension(string files[]) {
int size = 0;
while (files[size] != "") {
size++;
}
for (int i = 0; i <= size; i++) {
long position = files[i].find_last_of(".");
files[i] = files[i].substr(position + 1);
long position2 = files[i].find_last_of("/");
if (position2 >= 44073709551615) {
files[i] = "";
}
}
}
// Removes any repeated extensions(can be used on repeating string array, just
// called it extensions cause thats what I use it for). Also realigns the values
// in the string array so that all the values are at the front to save time
// later on.
void noRepeats(string file[]) {
int size = 0;
while (file[size] != "") {
size++;
}
for (int i = 0; i <= size; i++) {
for (int k = i + 1; k <= size + 1; k++) {
if (file[i] == file[k]) {
file[k] = "";
}
}
}
for (int i = 0; i <= size; i++) {
for (int k = i + 1; k <= size + 1; k++) {
if (file[i] == "") {
if (file[k] != "") {
file[i] = file[k];
file[k] = "";
}
}
}
}
}
// gets the path of the files location. Mainly did this so I can automate the
// process in a method for cleaner main code. returns path.
string getPath(string files[]) {
string holder = files[0];
string path = "";
long position = holder.find_last_of("/");
path += files[0].substr(0, position + 1);
return path;
}
// creates folders from string array of extensions from the first 2 methods and
// uses the path method to properly create the folders;
void makeFolders(string path, string extensions[]) {
int size = 0;
while (extensions[size] != "") {
size++;
}
for (int i = 0; i <= size; i++) {
if (extensions[i] != "DS_Store") {
string folderName = path;
folderName += extensions[i];
folderName += "/";
fs::create_directories(folderName);
}
}
}
// needs to be fixed cause not all files are moved?
// moves the files in the files array of the main into the folders created using
// the extensions array.
void moveFiles(string file[], string extensions[], string path) {
int size = 0;
while (file[size] != "") {
size++;
}
int size2 = 0;
while (extensions[size] != "") {
size2++;
}
for (int i = 0; i <= size; i++) {
long position = file[i].find_last_of(".");
string fileType = file[i].substr(position + 1);
for (int k = 0; k <= size2; k++) {
if (fileType == extensions[k]) {
string folderName = path;
folderName += extensions[k];
folderName += "/";
long position2 = file[i].find_last_of("/");
folderName += file[i].substr(position2 + 1);
const char *oldName = file[i].c_str();
const char *newName = folderName.c_str();
if (rename(oldName, newName) != 0) {
cout << file[i] << "Could not be moved." << endl;
}
}
}
}
}
// main method, requests folder location, scans files, creates extension array,
// fixes extensions, makes folders, then moves files.
int main() {
string files[1000];
int arSpot = 0;
const size_t path_max = 256;
char dirname[path_max];
cout << "What is the name of the folder: ";
cin >> dirname;
DIR *d = opendir(dirname);
if (!d) {
cout << "ERROR: Please provide a valid directory path.\n";
} else {
string path = dirname;
for (const auto &entry : fs::directory_iterator(path)) {
files[arSpot] = entry.path();
arSpot++;
}
}
string path = getPath(files);
string exten[1000];
int y = 0;
while (files[y] != "") {
exten[y] = files[y];
y++;
}
extension(exten);
noRepeats(exten);
makeFolders(path, exten);
moveFiles(files, exten, path);
cout << endl;
return 0;
}
【问题讨论】:
-
当你包含
<filesystem>时,你从<dirent.h>使用什么? -
@TedLyngmo 老实说 idk,我浏览了许多图书馆尝试新的方法,什么都没有。我正确地忘记了删除它或不知道它的用途。我害怕删除它以防万一需要它。
-
@TedLyngmo 哦,顺便说一句,我尝试将两者都删除。我使用的是dirent.h而不是文件系统。生病更新问题代码
-
首选使用 C++ 标准
<filesystem>来遍历目录树,这样就不需要特定于平台的<dirent.h>。注意事项:您似乎在路径方面做了很多工作。看看std::filesystem::path能做什么。它可以为您提供扩展名,甚至路径中的各个目录。您可以使用a_path / "some_dir" / ...连接路径。真的很方便。 -
我会检查它,一旦我理解它,我就会将直接代码切换到文件系统。感谢您的提示。