运用boost::filesystem和boost::program_options的小实例

1 篇文章 0 订阅

之前看代码的时候看到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(); 

以上。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值