使用C语言程序设计

一、标准输入流输出流和错误流

我们先写一段代码:

#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;
}

执行以下出现以下情况:


image.png

这里,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;
}

也是相同的结果,如下图所示:


image.png

因为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;
}

我们运行一下,结果如下:


image.png

我们通常会根据错误流的状态做重定向。

二、标准输入流输出流和错误流的重定向

先运行一段代码文件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; 
}

运行结果如下:


图片.png

1、标准输出流

在这里,我们在输入运行命令的时候多输入几个符号,像这样./a.out > a.txt,则会出现如下反应:

图片.png

在这里我们依然可以输入数字:
图片.png

输入完之后,看似没有什么反应,我们ll一下:
图片.png

我们发现多了一个a.txt文件,cat一下:
图片.png

我们可以发现原来之前输入到屏幕上的内容,都输入到了a.txt之中,这就叫标准输出流的重定向。

2、重定向

在此详细列出所有重定向:
1.>:输出重定向到一个文件或设备 覆盖原来的文件。
2.>!:输出重定向到一个文件或设备 强制覆盖原来的文件。
3.>>:输出重定向到一个文件或设备 追加原来的文件。
4.<:输入重定向到一个程序。
5.2>:将一个标准错误输出重定向到一个文件或设备 覆盖原来的文件(b-shell)
6.2>>:将一个标准错误输出重定向到一个文件或设备 追加到原来的文件
7.2>&1:将一个标准错误输出重定向到标准输出 注释:1 可能就是代表 标准输出
8.>&:将一个标准错误输出重定向到一个文件或设备 覆盖原来的文件(c-shell)

3、输入重定向

我们现在新建一个b.txt文件,详情如下:


图片.png

然后利用输入重定向将数字输入:


图片.png

我们可以看到我们写在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

图片.png

然后我们看一下目录里的文件:
图片.png

多了e.txt和r.txt,我们先看看r.txt:
图片.png

再看看e.txt:
图片.png

因为我们刚才除数输入的是0,所以输出了错误流,因此输入到了e.txt中。

三、管道符|

功能:将左边命令输出的结果作为右边命令的输入
举例:ls /etc/ | grep ab,grep命令是在输入文本中查询包含指定内容,该命令的意思就是,查询etc目录下所有的文件和目录然后通过管道输入到grep中,查询当中包含“ab”的内容,执行结果如下:

图片.png

四、通过管道符实现更复杂的功能

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:


图片.png

再运行avg.out:


图片.png

然后我们通过管道符将两个程序连接起来:
运行命令./add.out | ./avg.out

图片.png

这样,我们就通过管道符和两个小程序实现了更复杂的功能。

你可能感兴趣的:(使用C语言程序设计)