之前看代码的时候看到boost::filesystem和boost::program_options,顺便学习了一下(很粗浅的那种T_T),写了下面这个小程序练练手。
另外关于boost说一句,boost可认为是C++ STL的后备库,STL哪天心情好就会把一些boost的内容也加进去。boost库也像其他外部库一样,想要使用的话需要把它下载安装编译,在我的另一篇转载博客里面有相关教程,最后需要添加头文件目录,lib目录和添加lib等操作。
下面的程序有三个参数 --help,-I和-O,分别是帮助,输入路径和输出路径。功能是把输入路径的全部文本读进去,然后进行一些我们需要的中间操作,再把操作后的同名文本生成到输出路径。在这里为简单起见,中间操作是把输入文本的两个数相加,然后输出到输出文本中。
备注:输出路径应预先建立,程序里面没有提供新建输出路径的功能。(其实是我在这个环节上遇到了问题,但是偷懒没想怎么解决)
代码如下:
#include<iostream>
#include<string>
#include<fstream>
#include<vector>
#include<algorithm>
#include<boost/filesystem.hpp>
#include<boost/program_options.hpp>
using namespace std;
namespace fs = boost::filesystem;
namespace po = boost::program_options;
int main(int argc, char*argv[])
{
string input_dir, output_dir; //文件输入和输出路径
vector<fs::path> v;
double result[100];
po::options_description desc("Allowed options"); //构建参数目录
desc.add_options()
("help", "produce help message")
("input-dir,I", po::value<string>(&input_dir), "directory, with input file")
("output-dir,O", po::value<string>(&output_dir), "directory,where the output file will be saved");
po::variables_map mv;
po::store(po::parse_command_line(argc, argv, desc), mv);
po::notify(mv);
if (mv.count("help"))
{
cout << desc << endl;
return 1;
}
if (mv.count("input-dir"))
{
cout << "input: " << input_dir << endl;
}
if (mv.count("output-dir"))
{
cout << "output: " << output_dir << endl;
}
fs::path itr(input_dir);
if (fs::exists(itr)){ //路径是否存在
if (fs::is_directory(itr)){ //路径是不是目录
copy(fs::directory_iterator(itr), fs::directory_iterator(), back_inserter(v));
//遍历目录下的文件,把文件路径放进vector
sort(v.begin(), v.end());
int i = 0;
//显示文件名并做加法操作
for (vector<fs::path>::const_iterator it(v.begin()); it != v.end(); ++it)
{
cout << " " << *it <<endl; //输出文件名(用于调试)
double x, y;
ifstream inFile(it->string().c_str());
inFile >> x >> y;
result[i] = x + y;
inFile.close();
i++;
}
}
else
cout << "directory doesn't already exist" << endl;
}
else
cout << "path doesn't already exist" << endl;
int size = v.size();
fs::path otr(output_dir); //输出目录
fs::path otrfile; //输出目录下的文件路径
if (fs::is_directory(otr)){
for (int i = 0; i < size; i++){
otrfile = otr / v[i].filename();
//用"/"操作符构建文件路径,使输出文件名和输出文件名一样
ofstream outFile(otrfile.string().c_str());
outFile << result[i] << endl;
outFile.close();
}
}
system("pause");
return 0;
}
运行结果如下:(我的这个程序名叫testBat)
1. 在bat文件编写:
testBat.exe --help
pause
得到结果:
2.在bat文件编写:
testbat.exe -I E:/tmp/test -O E:/tmp/test2得到结果:
1. 在对目录做操作时(针对目录需要用户输入的情况,即程序在编译时不知道路径的具体值),应该先判断路径是否存在以及路径是否是目录。如:
fs::path itr(input_dir);
if (fs::exists(itr)){ //路径是否存在
if (fs::is_directory(itr)){ //路径是不是目录
copy(fs::directory_iterator(itr), fs::directory_iterator(), back_inserter(v));
//遍历目录下的文件,把文件路径放进vector
否则程序会报错。
2. 如果程序在编译时不知道路径的具体值,不能建立该路径。比如输出路径需要用户输入,即fs::path otr(output_dir);,此时如果执行下面代码,编译会报错
if (!fs::exists(otr))
fs::create_directories(otr);
这也是我不知道该如何新建输出路径的原因。(可能是我理解错了,如果大神路过,求指导)
3. 下面这句代码会出问题,得不到我想要的结果(虽然我看的代码是这样写的)。
otr=otr/vector[i].filename(); //获得输出文件路径
当然我每个循环都会重新把otr重置成目录,即
fs::path otr(output_dir);
但是还是会出问题,比如 otr的路径为"E:/tmp/test2",vector[i]的路径为"E:/tmp/test\\A1",按照我的想法,结果应该是otr=“E:/tmp/test2\\A1”,可结果otr居然为空。
这个问题我没想明白,然后就用了下面的代码解决(逃避问题了T_T)
fs::path otr(output_dir);
fs::path otrfile:
......
otrfile = otr / v[i].filename();
以上。