我想制作一個程式來讀取給定目錄中的檔案,為檔案的擴展名創建檔案夾,然后將檔案移動到新檔案夾中。
我對 C 相當陌生,因為我以前所做的所有事情都是在玩一些小東西,比如方法和類,所以我真的不知道出了什么問題。
程式第一次在檔案夾上運行時,它會正確創建所需的檔案夾,但不會移動檔案。
第二次運行時,沒有任何變化,但它使當前檔案夾的原始目錄的一組嵌套檔案夾。我的意思是,如果檔案夾目錄是A:/b/c/d/,它開始創建檔案夾b。我試過另一個檔案夾來測驗它,它確實正確地制作了檔案夾,但沒有移動檔案。
我添加了注釋以防代碼難以閱讀。我特意制作了用于制作檔案夾和將檔案移動到單獨方法中以便于編輯的邏輯。我應該注意,即使檔案沒有移動,該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;
}
uj5u.com熱心網友回復:
在for中環extension(),noRepeats(),makeFolders()并且moveFiles()都在各自的輸入陣列的邊界的外出。陣列是 0 索引的,它們的有效索引是[0..size-1]唯一的。您需要使用< size而不是<= sizewhile 回圈遍歷陣列。
就此而言,呼叫者應該將必要的size作為輸入引數傳入,函式不應該計算它。在main(),你知道的確切尺寸files[]陣列(arSpot)和exten[]陣列(y),所以通過這些值extension(),noRepeats(),makeFolders()和moveFiles()。
更好的是,根本不要使用原始陣列。使用std::vector替代,這是一個動態陣列,它知道自己的大小。當您使用它時,您可以將整個noRepeats()函式替換為std::set,它維護一個排序的唯一值串列。
另外,不要long用于字串索引,您應該使用string::size_typeorstd::size_t代替(甚至auto,讓編譯器決定)。
另外,究竟在if (position2 >= 44073709551615)尋找什么?您在呼叫 后立即執行此操作string::find_last_of(),因此您應該將結果與結果進行比較string::npos。
關于你的其余邏輯:
您沒有處理使用
\而不是/用作路徑分隔符的檔案夾路徑。extension()不考慮沒有擴展名的檔案在其路徑中有一個點的檔案夾中的可能性。main()不考慮其中包含空格的檔案夾路徑。
綜上所述,既然您已經知道該<filesystem>庫,您應該讓它為您完成所有艱苦的作業,例如:
#include <iostream>
#include <filesystem>
#include <vector>
#include <string>
#include <set>
using namespace std;
namespace fs = filesystem;
string getFileType(const fs::path &file) {
string ext = file.extension();
if (ext.size() > 1)
return ext.substr(1);
return "miscellaneous";
}
void makeFolders(const fs::path &folder, const set<string> &fileTypes) {
for (const auto &fileType : fileTypes) {
if (fileType != "DS_Store") {
fs::path newFolder = folder / fileType;
error_code ec;
fs::create_directories(newFolder, ec);
if (ec) {
cerr << newFolder << " Could not be created." << endl;
}
}
}
}
void moveFiles(const vector<fs::path> &files, const fs::path &folder) {
for (const auto &file : files) {
error_code ec;
fs::rename(file, folder / getFileType(file) / file.filename(), ec);
if (ec) {
cerr << file << " Could not be moved." << endl;
}
}
}
int main()
{
cout << "What is the path of the folder: ";
string dirPath;
getline(cin, dirPath);
error_code ec;
fs::directory_iterator dir(dirPath, ec);
if (ec)
{
cerr << "ERROR: Invalid directory path." << endl;
}
else
{
vector<fs::path> files;
set<string> fileTypes;
for (const auto &entry : dir) {
fs::path file = entry.path();
files.push_back(file);
fileTypes.insert(getFileType(file));
}
makeFolders(dirPath, fileTypes);
moveFiles(files, dirPath);
}
return 0;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/383213.html
