【问题标题】:Move a file that user chooses to another directory将用户选择的文件移动到另一个目录
【发布时间】:2021-06-07 13:50:24
【问题描述】:

我正在尝试制作一个程序,将用户指定的文件(如file.txt)移动到他也指定的目录。我尝试使用move()函数,但我还不太明白,所以我尝试使用rename()函数并使用this site的代码作为帮助。

我使用过rename() 函数并像这样移动了一个文件

char oldDir[] = "C:\\Users\\MyName\\file.txt";
char newDir[] = "C:\\Users\\MyName\\New folder\\file.txt";

if (rename(oldDir, newDir) != 0)
    perror("Error moving file");
else
    cout << "File moved successfully";

如果我正确输入了目录,那效果很好。问题是我想告诉用户输入一个文件的目录以移动到另一个目录,所以我尝试了这个:

char oldDir[] = " ";
char newDir[] = " ";
cout << "Type file directory: "; cin >> oldDir;
cout << "Type file directory to move to: "; cin >> newDir;
if (rename(oldDir, newDir) != 0)
    perror("Error moving file");
else
    cout << "File moved successfully";

但是,当在控制台中输入 oldDir 路径时,例如:C:\\Users\\MyName\\file.txt,我总是得到错误:

移动文件时出错,没有这样的文件或目录

在我输入newDir 路径之前它就返回了。当然file.txtC:\Users\MyName

可能是什么问题?我试图从oldDirnewDir 变量中删除" ",但随后又出现另一个错误:

不完整的类型是不允许的

我做错了什么?

【问题讨论】:

  • char oldDir[] = " "; 提供正好 2 个chars(空格和 0 终止符)的存储空间。如果有人键入多个字符,oldDir 存储空间不足。 (newDir 也一样。)我强烈建议改用std::string。 (您可以使用std::string::c_str() 访问原始C 字符串以在rename() 中使用它。)
  • 看看cplusplus.com/doc/tutorial/basic_io的“cin and strings”部分
  • 记录一下:是什么让char oldDir[] 成为一个完整的类型 使用" " 进行初始化,因为编译器决定了数组必须变成多大才能存储" " .因此,删除初始化不起作用。当然,您可以在括号中提供确切的数字,但我仍然建议使用 std::string 而不是 C char 数组。
  • @Scheff 所以我已经将变量 char oldDirnewDir 更改为 string oldDirnewDir 然后在 if 语句中添加 .c_str() ,我已经运行了程序并在该 file.txt 的目录中键入,我有错误说 "File exists" 即使我想移动文件而不是创建或者该错误要我说什么。 if (rename(oldDir.c_str(), newDir.c_str()) != 0)
  • 1.) 您的更改使程序运行。 2.)“文件存在”对我来说听起来像是操作系统的回应。所以,看看MS doc.: rename 这可能意味着什么。我假设您的错误是EACCES: newname 指定的文件或目录已存在或无法创建(路径无效);或者 oldname 是一个目录,而 newname 指定了不同的路径。您确定您使用的新名称的路径尚未被占用(来自之前的测试)?

标签: c++ file rename


【解决方案1】:

首先,在运行时在命令提示符下键入斜杠时,不要在斜杠上加倍,如果你正在这样做的话。转义斜线仅适用于代码中的string literals,不适用于运行时数据。

也就是说,您没有分配足够的内存来保存用户的输入。当使用" " 初始化时,您的oldDir[]newDir[] 数组的大小都只有2 个chars。当您删除 " " 时,编译器不再知道该数组有多大,因为您没有告诉它使用哪个大小。

您需要像这样处理数组:

char oldDir[MAX_PATH] = "";
char newDir[MAX_PATH] = "";

std::cout << "Type file directory: ";
cin.getline(oldDir, MAX_PATH); // paths can contain spaces!

std::cout << "Type file directory to move to: ";
cin.getline(newDir, MAX_PATH); // paths can contain spaces!

if (rename(oldDir, newDir) != 0)
    perror("Error moving file");
else
    std::cout << "File moved successfully" << std::endl;

但是,您确实应该改用 std::string

std::string oldDir, newDir;

std::cout << "Type file directory: ";
std::getline(cin, oldDir); // paths can contain spaces!

std::cout << "Type file directory to move to: ";
std::getline(cin, newDir); // paths can contain spaces!

if (rename(oldDir.c_str(), newDir.c_str()) != 0)
    perror("Error moving file");
else
    std::cout << "File moved successfully" << std::endl;

如果您使用的是 C++17 或更高版本,请考虑使用 std::filesystem::rename() 而不是 ::rename()

#include <filesystem>

std::string oldDir, newDir;

std::cout << "Type file directory: ";
std::getline(cin, oldDir); // paths can contain spaces!

std::cout << "Type file directory to move to: ";
getline(cin, newDir); // paths can contain spaces!

std::error_code err;
std::filesystem::rename(oldDir, newDir, err);
if (err)
    std::cerr << "Error moving file: " << err.message() << endl;
else
    std::cout << "File moved successfully" << std::endl;

【讨论】:

  • 所以我尝试了使用 C++ 17 的代码,并在输入目录(旧的和新的)时像这样:C:\Users\MyName\file.txt 然后 C:\Users\MyName\New folder ,名为“New folder”的文件夹获取该“file.txt”的名称。有点奇怪,因为它仍然说它是一个文件夹,我可以输入它。您能否尝试使用该代码?也许我做错了什么。
  • 如果oldDir 有文件名,则不能省略newDir 中的文件名。 std::filesystem::rename() 文档说:“如果 old_p 是非目录文件,则 new_p 必须是以下之一: - 与 old_p 相同的文件或指向它...;现有的非目录文件...;现有目录中不存在的文件。”甚至 C rename() 文档说:“如果 old 参数指向不是目录的文件的路径名,new 参数不应指向目录的路径名。”因此,要保留文件名,newDir 必须改为C:\Users\MyName\New folder\file.txt
猜你喜欢
  • 1970-01-01
  • 2017-07-20
  • 2014-07-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-26
相关资源
最近更新 更多