一、标准输入流输出流和错误流
我们先写一段代码:
#include
int main(){
printf("Hello world!\n");
printf("Please input any number,then press Enter\n");
int a;
scanf("%d",&a);
printf("input value is :%d\n,a");
return 0;
}
执行以下出现以下情况:
这里,scanf()
就是输入功能,它的第一个参数就是键盘输入的值,然后将其赋予到第二个参数变量中。我们输入的127896就通过这个函数赋予给了a变量。
printf()
则是输出功能,它将要输出的信息打印在显示屏中。
scanf()
和printf()
这两个函数都来自于stdio.h这个文件。
在运行a.out的时候,系统会开创一个进程,这个进程会加载stdio.h中的三个文件,分别是stdin标准输入文件stdout标准输出文件和stderr标准错误文件。
注:linux把所有设备都看作文件,把从摄像头、键盘、麦克风等设备读取信息视为从不同的类型的文件中读取信息,同理把网显示屏、音响、打印机等设备写入信息视为往不同的文件类习惯中写入信息。
标注输入文件即默认键盘为输入文件,标准输入文件即默认显示器为输入文件。所以刚才那段代码也可以写成下面的这种形式:
#include
int main(){
//printf("Hello world!\n");
fprintf(stdout,"Hello world!\n");
//printf("Please input any number,then press Enter\n");
fprintf(stdout,"Please input any number,then press Enter\n");
int a;
//scanf("%d",&a);
fscanf(stdin,"%d",&a);
//printf("input value is :%d\n,a");
fprintf(stdout,"input value is :%d\n,a");
return 0;
}
也是相同的结果,如下图所示:
因为printf()
就等同于fprintf(stdout, xxx)
,因为scanf()
就等同于fscanf(stdin, xxx)
,fprintf()除了能向显示器打印外,还能设置向打印机打印,fscanf()
除了接收键盘的信息外,还能接收别的,只要他们修改第一个参数即可。
我们再看一下错误流:
#include
int main(){
//printf("Hello world!\n");
fprintf(stdout,"Hello world!\n");
//printf("Please input any number,then press Enter\n");
fprintf(stdout,"Please input any number,then press Enter\n");
int a;
if(a<0){
fprintf(stderr,"The number must bigger than 0 or equals 0.\n");
return 1;
}
//scanf("%d",&a);
fscanf(stdin,"%d",&a);
//printf("input value is :%d\n,a");
fprintf(stdout,"input value is :%d\n,a");
return 0;
}
我们运行一下,结果如下:
我们通常会根据错误流的状态做重定向。
二、标准输入流输出流和错误流的重定向
先运行一段代码文件main.c:
#include
int main(){
printf("input the int value i:\n");
int i,j;
scanf("%d",&i);
printf("input the int value j:\n");
scanf("%d",&j);
printf("i+j=%d\n",i+j);
return 0;
}
运行结果如下:
1、标准输出流
在这里,我们在输入运行命令的时候多输入几个符号,像这样./a.out > a.txt
,则会出现如下反应:
在这里我们依然可以输入数字:
输入完之后,看似没有什么反应,我们ll一下:
我们发现多了一个a.txt文件,cat一下:
我们可以发现原来之前输入到屏幕上的内容,都输入到了a.txt之中,这就叫标准输出流的重定向。
2、重定向
在此详细列出所有重定向:
1.>
:输出重定向到一个文件或设备 覆盖原来的文件。
2.>!
:输出重定向到一个文件或设备 强制覆盖原来的文件。
3.>>
:输出重定向到一个文件或设备 追加原来的文件。
4.<
:输入重定向到一个程序。
5.2>
:将一个标准错误输出重定向到一个文件或设备 覆盖原来的文件(b-shell)
6.2>>
:将一个标准错误输出重定向到一个文件或设备 追加到原来的文件
7.2>&1
:将一个标准错误输出重定向到标准输出 注释:1 可能就是代表 标准输出
8.>&
:将一个标准错误输出重定向到一个文件或设备 覆盖原来的文件(c-shell)
3、输入重定向
我们现在新建一个b.txt文件,详情如下:
然后利用输入重定向将数字输入:
我们可以看到我们写在b.txt文件中的内容自动输入到了程序中。
4、标准错误流重定向
我们将代码改造一下:
#include
int main(){
printf("input the int value i:\n");
int i,j;
scanf("%d",&i);
printf("input the int value j:\n");
scanf("%d",&j);
if(j==0){
fprintf(stderr,"j can not equals 0");
return 1;
}
printf("i/j=%d\n",i/j);
return 0;
}
重新编译成a1.exe文件。
然后执行命令./a1.exe 1>r.txt 2>e.txt
然后我们看一下目录里的文件:
多了e.txt和r.txt,我们先看看r.txt:
再看看e.txt:
因为我们刚才除数输入的是0,所以输出了错误流,因此输入到了e.txt中。
三、管道符|
功能:将左边命令输出的结果作为右边命令的输入
举例:ls /etc/ | grep ab
,grep命令是在输入文本中查询包含指定内容,该命令的意思就是,查询etc目录下所有的文件和目录然后通过管道输入到grep中,查询当中包含“ab”的内容,执行结果如下:
四、通过管道符实现更复杂的功能
1、编写一个计算总数和计数的小程序“add”,
代码如下:
#include
int main(){
int number,sum,count;
sum=0;
count = 0;
while(1){
scanf("%d",&number);
if(0!=number){
sum+=number;
count++;
}else{
break;
}
}
printf("%d,%d\n",sum,count);
return 0;
}
2、编写一个计算平均值的小程序“avg”,
代码如下:
#include
int main(){
int sum, number;
float result;
scanf("%d,%d",&sum,&number);
if(0==number){
fprintf(stderr,"number can not equals 0.");
return 1;
}
result = sum/number;
printf("The average is %f\n", result);
return 0;
}
3、通过管道符连接两个程序
我们先分别运行一下两个程序看看结果如何?
先运行add.out:
再运行avg.out:
然后我们通过管道符将两个程序连接起来:
运行命令./add.out | ./avg.out
:
这样,我们就通过管道符和两个小程序实现了更复杂的功能。