我有50个图像文件,我想重命名。
:img (1) - Copy.jpg
to:picture_1.jpg
你知道更优雅的写法吗?我想到了这个:
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
int main()
{
string oldname = "";
string newname = "";
char oldfilename[20];
char newfilename[30];
for (int i = 1; i <= 50; i++)
{
oldname = "img ("+ to_string(i) +") - copy.jpg"; // old file name
newname = "picture_" + to_string(i) + ".jpg"; // new file name
strcpy(oldfilename, oldname.c_str());
strcpy(newfilename, newname.c_str());
if (rename(oldfilename, newfilename) != 0)
perror("Error renaming file");
else
{
cout << oldfilename << " renamed successfully to " << newfilename << endl;
}
}
char c;
cin >> c;
return 0;
}
这听起来像是x - y问题。为什么要用c++来实现呢?
如果您坚持使用c++(不要与C混淆),那么您应该避免使用char
数组和strcpy
及其同类。特别是,strcpy
是非常危险的(至少使用strncpy
,它不会溢出缓冲区)。
通过使用c++ 17和c++ 20的特性,代码可以得到很大的改进。特别是,可以使用std::format()
来格式化文件名(如果编译器还不支持此功能,则使用{fmt}库):
for (int i = 1; i <= 50; ++i) {
auto oldname = std::format("img ({}) - copy.jpg", i);
auto newname = std::format("picture_{}.jpg", i);
使用c++ 17的std::fileystem::rename()
来重命名文件,而不需要使用C函数:
try {
std::filesystem::rename(oldname, newname);
} catch (std::filesystem::filesystem_error &err) {
std::cerr << std::format("Error renaming file: {}n", err.what());
}
}
如果你的编译器还不支持std::filesystem
,你可以使用boost::filesystem
。
我将简化提问者所拥有的内容,并应用一些通用的最佳实践。为了便于比较,我坚持使用老派的c++代码。注释解释了我做了什么和为什么,以保持解释接近他们所解释的。
#include <iostream>
#include <cstdio>
#include <string>
// using namespace std should only be used under controlled circumstances
// if at all.
int main()
{
// removed all variables
for (int i = 1; i <= 50; i++)
{
// Keep variable definitions close to usage unless you have a good
// reason not to. Can't think of any good reasons.
std::string oldname = "img ("+ std::to_string(i) +") - copy.jpg";
std::string newname = "picture_" + std::to_string(i) + ".jpg";
// no need for the char arrays or the strcpys. Instead we will use the
// std::string::c_str function to get the string's backing array
// If C++17 or newer is available we could use std::filesystem::rename.
// I'm leaving off the std:: prefix on rename because C is all we need
if (rename(oldname.c_str(), newname.c_str()) != 0)
{ // I find that always using the optional braces prevents future bugs.
// That's a personal opinion and choice.
perror("Error renaming file");
}
else
{
std::cout << oldname << " renamed successfully to " << newname << std::endl;
}
}
char c;
std::cin >> std::noskipws >> c; // >> c will ignore whitespace, so the user
// cannot advance simply by pressing enter.
return 0;
}
关于注释的说明。如果不能从代码和变量名推断出代码的目的,请考虑更改代码。只注释那些不管你怎么重做仍然晦涩难懂的东西。