小知识点:使用文件重定向;STL中的map按值排序。

Contents

前言文件重定向把 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)中。

如果我直接执行这个程序的话,是要从控制台上手动输入:姓名、成绩。但是我用重定向的话就不用手动输入了,它会自己从文件中获取值。

bfc58d6f74160e4587d4cf813707a5be.png

看最后一行,前面的都是在切换路径。

结果:

6956e1edbd0359aa5a84a1d0bdcd7471.png


redirection.exe <./in.txt >./out.txt

可执行程序 < 替换标准输入cin的文件 > 替换标准输出cout的文件

Note:上面的 >替换标准输出cout的文件 是以覆盖的方式输出到文件中。如果我们想以追加的方式,用两个箭头就行。

redirection.exe <./in.txt >>./out.txt

可执行程序 < 替换标准输入cin的文件 > 替换标准输出cout的文件(追加)

把另一个文件中的及格的同学 追加到out.txt中:

effb4587383eb1c3f9627bd650417fd3.png


f0a88ffee46d0782510548c07347733b.png

总结

其实这个你也可以通过给main()函数传递参数来实现,判断传入的参数的个数,如果没传参数就从 cin / cout 中获取/输出值,如果传了参数就从文件中 获取/输出值。不过用这种重定向的方式应该更方便点吧。

另外在Linux中的重定向也是使用相同的符号来实现重定向,不过 可以在那两种重定向符号前面加上 &。即:&> 或者 &>>这样的话既可以保留正确的输出,也可以保留错误的输出,具体就不演示了。

把 STL map 里的元素按照值进行排序

自己做了上面的这个例子,然后又想到一个问题,怎么把装了学生成绩的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;
}

结果:

91d66b2e96b8b6e8458adbf1c8315302.png



d96927279a78b67a1f79682cdd521a9e.jpeg

f0e2ca2956ea81b5565dbd629cbb9913.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值