如果你对管道和重定向应用自如了,无需继续往下看。本文虽然以windows上cmd命令行环境演示,但同样适用于Unix/Linux等平台。

引言

关于管道和重定向,最初是在刘汝佳的《算法竞赛入门经典》上看到的,也是从那时开始用gcc(MinGW) & notepad++(在此之前,Linux上用的是Eclipse+CDT,windows上是VC)。一般操作系统的命令行环境下都提供了管道和重定向工具,看了刘汝佳的书才知道用txt代替键盘作输入、测试是多么的方便!回想起每次点完GO之后一个数字一个数字的按键盘(而且笔记本键盘的数字键按起来没有独立键盘的数字区按起来那么爽)还不时按错的痛苦经历,决定今日将这一强大的工具与大家分享。

从A+B说起

练过OJ的同学可能对此深有体会(没练过没有关系),你的程序可能要先读10个输入(或者更多),才出结果;而你有很难保证这个程序一次编译就是对的,每次修改后都要重新输入这一堆数(还时不时的输错),实在让人难以忍受!刘的书中说了两种方法:

一.利用C标准库提供的“重定向函数”freopen("input.txt",  "r", stdin);这种方法适合用在IDE上,添加一行代码,再准备一个文本文件,你不用单独打开一个cmd窗口,也能够让input.txt的文本带你的所有键盘输入。缺点就是你要在提交之时将这句代码注释掉(或者删掉);相信不少同学在提交的时候因为忘了注释这句而WA的。(在有的IDE上找源代码文件所在目录也不是很方便。)

下面就以经典的A+B问题为例。如下是A+B问题的一个解法,其中input.txt是事先已经准备好的测试数据,并且和这个代码文件放在同一目录下(VC上是这样,有的IDE可能要和.exe放到同一目录):

#include <stdio.h>

int main()
{
int a,b;
freopen("input.txt", "r", stdin);
    while( scanf("%d%d", &a, &b) == 2 )
    {
        printf( "%d\n", a+b );
    }
return 0;
}

二.命令行环境下的————重定向。后面重点介绍。

使用重定向的代码不需要做任何手脚(假设保存为D:\OJ\aplusb.c):

#include <stdio.h>

int main()
{
int a,b;
while( scanf("%d%d", &a, &b) == 2 )
{
printf( "%d\n", a+b );
}
return 0;
}

下面就以编译、测试位于D:\OJ目录下的aplusb.c的步骤为例:

  1. (要使用重定向你必须)先打开一个cmd窗口,并让cmd窗口的当前目录为D:\OJ。

    win7上只需打开D:\OJ文件夹,按住SHIFT键,在窗口的空白处右击鼠标,点“在此处打开窗口”即可。





    win xp上稍显麻烦,

    step1. WinKey+R弹出运行窗口,键入“cmd”回车,

           弹出的cmd窗口显示当前目录是C:\Document and Setting\xxx(win7则是C:\Users\xxx);

    step2. 再键入“D:”回车,跳转到D盘;

    step3. 再用cd命令跳转到当前exe所在目录(如果目录名较长,可以从资源管理器的路径栏上copy)。

    win7上当然也可以这么做,如下:

  2. 编译aplusb.c

    假设你已经设置好了环境变量(如果你还没有安装配置命令行工具,点击这里):

    gcc aplusb.c 

    将会有a.exe生成(如果想以其他名称输出加上-o选项,如gcc -o OutName.exe aplusb.c);
  3. 测试a.exe

    假设你已经准备好了一份测试数据,并以input.txt保存在相同目录(D:\OJ)下(如果没有,创建一个),则可以:

    a.exe < input.txt

    程序a.exe将会直接运行,并且以input.txt为输入;

    这里的<符号叫重定向输入符(它右边的文件将替换左边程序或命令的标准输入(cmd窗口输入))

    如input.txt内容如下:

    1 2 

    3 4

    5 6

    7 8

    9 10

    100 200

    200 400

    400 800

    20000 30000

    5000000 6000000

    70000000 80000000

    运行gcc和a.exe后:

升级

A+B问题太简单?现在换一个问题:
•统计问题

一组整数,统计最大值、最小值、平均值
•输入

第一行一个32位整数n表示测试数据个数,接下来的n行每行一个非负32位整数
•输出

一行,最小值、最大值、平均值,空格分开
这个问题也比较简单;之所以举这个例子,只是为了突出重定向和管道的重要作用。
相信只要学过一点编程的都能立刻写出来:
(这段程序里有个小错误,稍后现形)
保存为D:\OJ\Perls\sovle2.cpp
这里也有一份测试数据input.txt:

10

20

30

40

50

60

70

80

90
编译:
gcc solve2.cpp -o solve.exe
测试:
solve.exe < input.txt

结果正确!

随机数生成器

你可能对上面的一组测试数据不够满意,太少,太小,太弱?

下面写一个能够生成满足题目输入格式的随机数生成器:

保存为rand_gen.c

该程序读入n,输出n及n个随机数(正如题目输入格式)。

编译:

gcc rand_gen.c -o randgen.exe

运行:

这时你可使用重定向输出符(它右边的文件将替换标准输出(cmd窗口输出)):
randgen.exe > rand_data.txt
再用重定向输入进行测试:

solve.exe < rand_data.txt

管道

在已经有randgen.exe的情况下,使用管道更加方便:

echo 10 | randgen.exe


echo是回显程序,echo 10将会输出10

“|”是管道符号,它将会把左边的程序(或命令)的输出重定向到右边程序(或命令)的输入.
这里的效果和前面手工输入10是一样的。

管道可以连接使用;所以,我们可以这样:
echo 10 | randgen | solve

(.exe可以不用输入)

过程是这样的:

echo 10 ==10==> randgen.exe ==(临时数据)===> solve.exe -> 屏幕输出

这次测试出现了问题,最小值和平均值竟然都是负数!

查看一下代码发现这里有两个问题:

i.无符号整数应该用unsigned int;
ii.sum溢出,应该用double;
更正:

保存为final_solve.c

再次编译测试:



附录

windows官方参考使用命令重定向操作符:

http://technet.microsoft.com/zh-cn/library/cc772622(WS.10).aspx

Unix/Linux平台,参考文章:

http://man.chinaunix.net/linux/mandrake/101/zh_cn/Command-Line.html/shell-pipes.html

命令行环境下简单实用的工具——重定向&管道的更多相关文章

  1. 惊艳的cygwin——Windows下的Linux命令行环境的配置和使用

    http://www.tuicool.com/articles/2MramqI 时间 2014-07-29 09:28:36  点滴之间 聚沙成金 原文  http://www.path8.net/t ...

  2. Ubuntu下几个命令行方式使用的图片浏览工具

    想找几个Ubuntu下可以以命令行方式使用的图片浏览工具. Google了一些资料,找到下面几个web: 1.pho:轻巧的命令行图片查看器 其中介绍了工具pho,其功能特点,见下面的转帖内容: ph ...

  3. 7个基于Linux命令行的文件下载和网站浏览工具

    7个基于Linux命令行的文件下载和网站浏览工具 时间:2015-06-01 09:36来源:linux.cn 编辑:linux.cn 点击: 2282 次 Linux命令行是GNU/Linux中最神 ...

  4. 如何在命令行模式下查看Python帮助文档---dir、help、__doc__

    如何在命令行模式下查看Python帮助文档---dir.help.__doc__ 1.dir函数式可以查看对象的属性,使用方法很简单,举str类型为例,在Python命令窗口输入 dir(str) 即 ...

  5. 在windows命令行窗口下执行:查看所有的端口占用情况

    开始--运行--cmd 进入命令提示符 输入netstat -ano 即可看到所有连接的PID 之后在任务管理器中找到这个PID所对应的程序如果任务管理器中没有PID这一项,可以在任务管理器中选&qu ...

  6. Linux命令行环境与桌面环境护切换

    1.前言 在大部分情况下,我们在使用Linux时习惯使用命令行环境,但是有时候也还是会使用到安装桌面环境,所以在这里介绍一下如何给没有安装桌面环境的系统安装桌面环境.以Centos 6.5 为例演示一 ...

  7. mplayer命令行模式下的使用方法【转】

    mplayer命令行模式下的使用方法http://hi.baidu.com/lovehack2006/blog/item/162ef9778214111eb051b9d4.htmlMPlayerMPl ...

  8. 在命令行模式下查看Python帮助文档---dir、help、__doc__

    在命令行模式下查看Python帮助文档---dir.help.__doc__   1.dir函数式可以查看对象的属性,使用方法很简单,举str类型为例,在Python命令窗口输入 dir(str) 即 ...

  9. 在命令行cmd 下,输入dxdiag 查看关于电脑许多硬件的详细信息

    输入命令就可以查看本机的很多硬件的详细信息: 在命令行cmd 下,输入dxdiag  查看关于电脑许多硬件的详细信息

随机推荐

  1. Javascript 获取链接(url)参数的方法

    有时我们需要在客户端获取链接参数,一个常见的方法是将链接当做字符串,按照链接的格式分解,然后获取对应的参数值.本文给出的就是这个流程的具体实现方法. 当然,我们也可以用正则直接匹配,文章中也给出了一个 ...

  2. Go学习

    简介 Go语言是Google出了一个语言,基本概念我就不介绍了, GO语言从原生上支持高并发,并提供了简单的调用方式,我们就重点研究一下它的高并发 进程与线程 在介绍高并发之前,我们需要了解一下我们现 ...

  3. System.Diagnostics.Process 启动进程资源或调用外部的命令的使用

    经常看到一些程序在保存为一个txt,或者excel的文件的时候,保存完毕立即打开, 启动程序或打开文件的代码 System.Diagnostics.Process.Start(System.IO.Pa ...

  4. MyISAM 和InnoDB 的区别.(存储,索引, 事务, 锁)

    MyISAM类型的表强调的是性能,但是不支持事务.及外部键等高级功能. MySQL默认采用的是MyISAM. MyISAM不支持事务,而InnoDB支持.InnoDB的AUTOCOMMIT默认是打开的 ...

  5. 使用antd UI 制作菜单

    antd 主页地址:https://ant.design/docs/react/introduce 在使用过程中,不能照搬antd的组件代码,因为有些并不合适.首先,菜单并没有做跳转功能,仅仅是菜单, ...

  6. Dirac Delta Function

    也称为Degenerate pdf, 退化概率密度函数. 未经考证的解释是: 当正态分布的\(\sigma \to 0\)时, 正态分布就退化为这个分布了. 定义 \[ \delta(x) = \be ...

  7. Android只能动态注册的广播Action

    只能动态注册的广播(部分): android.intent.action.SCREEN_ON android.intent.action.SCREEN_OFF android.intent.actio ...

  8. python中引入包的时候报错AttributeError: module 'sys' has no attribute 'setdefaultencoding'解决方法?

    python中引入包的时候报错:import unittestimport smtplibimport timeimport osimport sysimp.reload(sys)sys.setdef ...

  9. 【Codeforces715C&716E】Digit Tree 数学 + 点分治

    C. Digit Tree time limit per test:3 seconds memory limit per test:256 megabytes input:standard input ...

  10. jmeter测试 常用数据库的性能

    在线程组中设置线程属性,执行次数=线程数*循环次数 本次JOB共插入了5W条记录,从14:56:46开始到15:01:29结束共耗时343s,平均145.8条/s. 同理sql sever:从15:2 ...