标准输入
将键盘或终端其他设备的输入存储的位置(自己理解瞎定义的),一般使用'<'操作符告诉操作系统,标准输入的来源,默认情况下从键盘和终端读取数据
eg:./demo < input.txt 表示运行demo程序的数据来源是input.txt文件
标准输出
将显示在屏幕的输出存储的位置(自己理解瞎定义的),一般使用'>'操作符告诉操作系统,标准输出的位置,默认情况下会发送到显示器
eg:./demo > output.txt 表示运行demo程序产生的结果输出到output.txt文件
为什么要使用标准输入,标准输出?
因为一旦有了标准输入,标准输出,就可以重定向标准输入,标准输出,让程序从键盘以外的地方读取数据,往显示器以外的地方写数据
标准输入与标准输出的实例
#include <stdio.h>
int main()
{
float latitude;
float longitude;
char info[80];
int started=0;
puts("data=[");
while (scanf("%f,%f,%79[^\n]", &latitude, &longitude, info) == 3) {
if (started) {
printf(",\n");
} else {
started = 1;
}
printf("{latitude:%f, longitude:%f, info:'%s'}", latitude, longitude, info);
}
puts("\n]");
return 0;
}
input.txt内容为:
12.12,22.33,speed=21
33.33,45.21,speed=24
12.44,55.32,seppd=44
11.55,44.33,speed=22
423.63182,-71.095833,speed=22
28.345,-74.232,speed=44
以上程序在tool.c的文件中,gcc tool.c -o tool && ./tool < input.txt > output.txt
程序的标准输入是input.txt文件,标准输出到了output.txt文件
如果程序出错了如何看到结果?
程序执行完之后再终端输入:echo $?
如果返回结果是0代表正常执行,如果返回结果是其他值,就是程序中报错的值(main函数正常返回0)
如果其中一条数据出错了怎么办?终止程序的运行,错误的信息也写入到了output.txt?
我们需要将正常输出和异常输出分开来
标准错误
将错误的信息输出的位置,一般使用fprintf(stderr,msg)进行输出
例子:
#include <stdio.h>
int main()
{
float latitude;
float longitude;
char info[80];
int started = 0;
puts("data=[");
while (scanf("%f,%f,%79[^\n]", &latitude, &longitude, info) == 3) {
if (started) {
printf(",\n");
} else {
started = 1;
}
if ((latitude < -90.0) || (latitude > 90.0)) {
fprintf(stderr, "Invoid latitude : %f\n", latitude);
return 2;
}
if ((longitude < -180.0) || (longitude > 180.0)) {
fprintf(stderr, "Invoid latitude : %f\n", latitude);
return 2;
}
printf("{latitude:%f, longitude:%f, info:'%s'}", latitude, longitude, info);
}
puts("\n]");
return 0;
}
以上程序在tool.c的文件中,gcc tool.c -o tool && ./tool < input.txt > output.txt
程序的标准输入是input.txt文件,标准输出到了output.txt文件,标准错误输出到了终端的显示界面上
管道
将一个进程的标准输出与另一个进程的标准输入连接起来。用符号'|'表示
一个例子:
#include <stdio.h>
int main()
{
float latitude;
float longitude;
char info[80];
while(scanf("%f, %f, %79[^\n]", &latitude, &longitude, info) == 3) {
if ((latitude > 26) && (latitude < 34)) {
if ((longitude > -76) && (longitude < -64)) {
printf("%f, %f, %s\n", latitude, longitude, info);
}
}
}
return 0;
}
以上程序在filter.c的文件中,gcc filter.c -o filter && (./filter | ./tool < input.txt > output.txt
程序的标准输入是input.txt文件,标准输出到了output.txt文件,标准错误输出到了终端的显示界面上
如果我需要把数据进行分类输出到多个文件中呢?标准输出和标准错误输出只有两种形式,满足不了需求怎么办?
需要在程序运行时创建自己的数据流
读取数据
FILE *in_file = fopen("input.txt", "r");
fscanf(in_file, "%79[^\n]\n", demo);
写入数据
FILE *out_file = fopen("output.txt", "w");
fprintf(out_file, "this is %s", "demo");
关闭数据流
fclose(in_file);
fclose(out_file);
创建数据流例子
以下是file.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
argc代表传入函数main的参数的个数
argv表示实际的参数数组
*/
int main(int argc, char *argv[])
{
char line[80];
/*
argc第0个参数是函数名,所以一共有6个参数
*/
if (argc != 6) {
fprintf(stderr, "you need to give 5 arguments\n");
return 1;
}
/*
注意:一定要是双引号,写别的语言惹的祸
*/
FILE *in = fopen("spooky.csv", "r");
FILE *file1 = fopen(argv[2], "w");
FILE *file2 = fopen(argv[4], "w");
FILE *file3 = fopen(argv[5], "w");
/*
用fscanf读取自定义数据流
*/
while(fscanf(in, "%79[^\n]\n", line) == 1) {
if (strstr(line, argv[1])) {
/*
用fprintf输出自定义数据流
*/
fprintf(file1, "%s\n", line);
} else if (strstr(line, argv[3])) {
fprintf(file2, "%s\n", line);
} else {
fprintf(file3, "%s\n", line);
}
}
fclose(file1);
fclose(file2);
fclose(file3);
return 0;
}
以下是spooky.csv
30.453,-68.1212,Type=Yeti
28.2342,-74.1212,Type=UFO
29.303.-71.1323,Type=Ship
28.1212,-62.2342,Type=Elvis
27.1313,-68.1212,Type=Goatsucker
30.12123,-73.12132,Type=Disappearance
26.121,-71.123213,Type=UFO
29.12,-66.1212,Type=Ship
37.234,-69.23424,Type=Elvis
22.234,-68.23424,Type=Elvis
27.234,-87.23424,Type=Elvis
运行:gcc file.c -o file && ./file UFO aliens.txt Elvis elviss.txt the_rest.txt
会得到多个自定义的输出流:aliens.txt,elviss.txt
# 函数参数的传入太过复杂,该如何处理呢?
使用unistd.h替代函数参数的处理
# 函数参数处理的例子
#include <stdio.h>
#include <unistd.h>
/*
argc代表传入函数main的参数的个数
argv表示实际的参数数组
*/
int main(int argc, char *argv[])
{
char *delivery = "";
int thick = 0;
int count = 0;
char ch;
while((ch = getopt(argc, argv, "d:t")) != EOF) {
switch(ch) {
case 'd':
delivery = optarg;
break;
case 't':
thick = 1;
break;
default:
fprintf(stderr, "Unknow option: '%s'\n", optarg);
return 1;
}
}
argc -= optind;
argv += optind;
if (thick) {
puts("thick crust");
}
if (delivery[0]) {
printf("to be delivered %s.\n", delivery);
}
puts("Ingredients:");
for(count = 0; count<argc;count++) {
puts(argv[count]);
}
return 0;
}
gcc unistd.c -o unistd
./unistd Anchovies Pineapple
./unistd -d now Anchovies Pineapple
./unistd -d now -t Anchovies Pineapple
./unistd -f