前言文件重定向把 STL map 里的元素按照值进行排序
嗯,有半个来月没写过推送了, 一直想把之前在 51cto 上学的那个 C++ Socket 网络编程 给总结一下。总感觉东西都点多,最近也啥心情和时间整理。就写两个小知识点吧。
文件重定向,把文件作为系统的标准输入或者标准输出。我觉得应该叫标准输入/输出重定向吧,不过C++ Primer上说是文件重定向。
将STL的map按照值排序(map默认按照 key 来排序)。
这里用一个简单的例子来演示:
一个文件中保存了每个学生的名字以及学生的成绩,我们把及格的学生拎出来(把名字和成绩打印出来)。
直接上代码吧:
#include <iostream> #include <algorithm> #include <iterator> #include <map> #include <vector> #include <string> using namespace std; int main() { /// 姓名:成绩 // map<string, string> score; vector<string> all_; /// 把 姓名和成绩 从标准输入 拷贝到 vector 中 copy(istream_iterator<string>(cin), istream_iterator<string>(), back_inserter(all_)); /// 筛选成绩 for (int i = 0; i < all_.size(); i += 2) { /// 没有做容错处理,可能输入错误,只有名字没有成绩那种或者姓名中间中间有空格 // if (stoi(all_.at(i+1)) >= 60) score[all_.at(i)] = all_.at(i+1); } /// 把及格的成绩(包括姓名)拷贝到 标准输出! for (const auto& ele : score) { cout << ele.first << "\t\t" << ele.second << endl; } getchar(); return 0; }我这个代码中是从 标准输入(cin)获取值,然后筛选后输出到 标准输出(cout)中。
如果我直接执行这个程序的话,是要从控制台上手动输入:姓名、成绩。但是我用重定向的话就不用手动输入了,它会自己从文件中获取值。
看最后一行,前面的都是在切换路径。
结果:
redirection.exe <./in.txt >./out.txt 可执行程序 < 替换标准输入cin的文件 > 替换标准输出cout的文件Note:上面的 >替换标准输出cout的文件 是以覆盖的方式输出到文件中。如果我们想以追加的方式,用两个箭头就行。
redirection.exe <./in.txt >>./out.txt 可执行程序 < 替换标准输入cin的文件 > 替换标准输出cout的文件(追加)把另一个文件中的及格的同学 追加到out.txt中:
总结
其实这个你也可以通过给main()函数传递参数来实现,判断传入的参数的个数,如果没传参数就从 cin / cout 中获取/输出值,如果传了参数就从文件中 获取/输出值。不过用这种重定向的方式应该更方便点吧。
另外在Linux中的重定向也是使用相同的符号来实现重定向,不过 可以在那两种重定向符号前面加上 &。即:&> 或者 &>>这样的话既可以保留正确的输出,也可以保留错误的输出,具体就不演示了。
自己做了上面的这个例子,然后又想到一个问题,怎么把装了学生成绩的map按照学生成绩来进行排序呢?
首先得提一下,STL 的map中的元素也是有序的,不过它是按照 Key 的字典序进行排序的。可以看看 map 的源码:
template < class Key, // map::key_type class T, // map::mapped_type class Compare = less<Key>, // map::key_compare class Alloc = allocator<pair<const Key,T> > // map::allocator_type > class map;可以看到它的第三个模板参数,就是控制 map 中的Key的排序方式,而且默认是字典序由小到大。
那么如何让STL map里的元素按照值大小排序呢?很遗憾,我们貌似并不能在map中 让map的元素按照值来排序。
不过我们可以借助vector,把map中的所有pair放到vector中,然后对pair定义一个比较函数,再用sort,就能完成这项排序工作了!
具体代码如下:
#include <map> #include <vector> #include <string> #include <algorithm> #include <iostream> using namespace std; /// 定义比较函数 (由小到大)// bool pair_cmp(const pair<string, string>& p1, const pair<string, string>& p2) { return stoi(p1.second) < stoi(p2.second); 把整数字符串转化成整数 // } /// 重载 pair<string, string> 的 << 操作符函数 // ostream& operator<<(ostream& os, const pair<string, string>& p) { os << p.first << "\t\t" << p.second; return os; } /// 借助 vector 把map中的元素按值大小顺序放入 vector中 vector<pair<string, string>> sort_map_by_value(const map<string, string>& score) { vector<pair<string, string>> res(score.begin(), score.end()); sort(res.begin(), res.end(), pair_cmp); return res; } /// 打印排序后的 map void show_sorted_map(const vector<pair<string, string>>& vec_pair) { for (const auto& ele : vec_pair) cout << ele << endl; }结果: