可以用重定向

在用scanf()从键盘读取数据、printf()向显示器写数据时,这两个函数其实并没有直接使用键盘、显示器,而是用了标准输入和标准输出。程序运行时,操作系统会创建标准输入和标准输出。

可以用重定向 - 图1

操作系统控制数据如何进出标准输入、标准输出。如果在命令提示符或终端运行程序,操作系统会把所有键盘输入都发送到标准输入;默认情况下,如果操作系统从标准输出中读到数据,就发送到显示器。

scanf()printf()函数并不知道数据从哪里来,也不知道数据要到哪里去,它们也不关心这点,它们只管从标准输入读数据,向标准输出写数据。

听起来有些故弄玄虚,为什么不让程序直接使用键盘和屏幕呢?岂不是更简单?

操作系统为什么要使用标准输入、标准输出与程序交互呢?有一个很好的原因:

因为这么一来,就可以重定向标准输入、标准输出,让程序从键盘以外的地方读数据、往显示器以外的地方写数据,例如文件。

可以用 < 重定向标准输入……

你不必再用键盘输入数据,可以使用 < 操作符从文件中读取数据。

可以用重定向 - 图2

<操作符告诉操作系统,程序的标准输入应该与gpsdata.csv文件相连,而不是键盘,所以可以把数据从文件发送到程序。现在只需重定向程序的输出。

可以用重定向 - 图3

用 > 重定向标准输出

为了把标准输出重定向到文件,需要使用 > 操作符:

可以用重定向 - 图4

因为重定向了标准输出,所以屏幕上没有出现任何数据,程序现在创建了一个叫output.json的文件。

地图应用需要用到output.json文件,让我们看看地图能否工作。

可以用重定向 - 图5

 

可以用重定向 - 图6试驾

试试新创建的数据文件能否在地图上画出坐标,把含有地图程序的网页复制到output.json所在的文件夹中,然后用浏览器打开网页。

可以用重定向 - 图7

地图工作了。

网页中的地图成功读取了输出文件中的数据。

可以用重定向 - 图8

一些数据出错了……

程序已经能够顺利读取GPS数据,并把数据转化为地图应用需要的格式。但是几天以后,程序出现了一个问题。

可以用重定向 - 图9

geo2json程序并不会检查读入的数据,它只是改变数字的格式,然后把它们发送到输出文件。

这个问题应该不难解决,你需要校验数据。

可以用重定向 - 图10练习

你需要在geo2json程序中添加一些代码,用来检查错误的经、纬度值。无需任何高深的技巧。假如经度或纬度不在指定的范围内,就显示一条错误消息,并在退出程序的同时把错误状态码置为2:

可以用重定向 - 图11

 

可以用重定向 - 图12练习

你在geo2json程序中添加一些代码,用来检查错误的经、纬度值。假如经度或纬度不在指定的范围内,就显示一条错误消息,并在退出程序的同时把错误状态码置为2:

可以用重定向 - 图13

可以用重定向 - 图14试驾

好啦,代码现在可以检查经度、纬度的范围了,程序能发现错误数据吗?我们拭目以待。

编译代码,使用错误数据作输入,运行程序:

可以用重定向 - 图15

太奇怪了,明明加了检查错误的代码,但运行程序时,一切还是老样子,但这次地图上一个坐标都没有,这是为什么?

可以用重定向 - 图16脑力风暴

好好研究一下这段代码,你认为发生了什么?代码有没有照你说的去做?为什么连一条错误消息都没有?为什么地图应用认为整个output.json文件是错的?

代码拆析

可以用重定向 - 图17

既然地图程序在埋怨output.json文件,那我们就打开它,看看里面是什么:

可以用重定向 - 图18

一打开文件,你就可以看得一清二楚。当程序一看到错误数据就马上退出了,它不再继续处理数据,而是输出了一条错误消息。当把标准输出重定向到output.json,也重定向了错误消息,于是程序一声不吭地结束,你永远不知道问题出在哪里。

如果你看得到错误消息,就会去检查程序的退出状态,但你现在连程序出错了都不知道。

怎样才能在重定向输出的同时显示错误消息呢?

可以用重定向 - 图19百宝箱

程序在数据中发现错误就会退出,并把退出状态置为2。怎么在程序结束后检查错误状态呢?要看操作系统,如果你的计算机是Mac、Linux、其他UNIX,或你在Windows上使用Cygwin,可以用以下命令显示错误状态:

可以用重定向 - 图20

如果用的是Windows的命令提示符,则可以输入:

可以用重定向 - 图21

这两条命令做了相同的事:显示程序结束时返回的那个数字。

可以用重定向 - 图22