首先,明确一下标准输入,标准输出,标准错误输出这三个概念与键盘输入,显示器输出的区别,只是因为我们通常默认标准输入是键盘,标准输出和标准错误输出是显示器而已,其他的就没有太大关联了。
//程序保存在lianxi.c文件中,putchar()与getchar()字符输入输出
#include<stdio.h>
int main()
{
char number[20];
int j,i=0;
while((number[i]=getchar())!=EOF)
++i;
printf("the number i is %i\n",i);//检查输入了几个字符,若是用键盘输入,则使用ctrl+d组合输入EOF
for(j=0;j<i;j++)//因为最后输入结束时按下enter后再输入ctrl+d,所以字符串最后一个字符是换行符
printf("%c",number[j]);
}
如果直接编译运行lianxi.c,则输入由键盘,
可以使用重定向 /lianxi < infile (将infile中的数据作为标准输入给程序)
格式化输出
int printf(char* format,变元1,变元2,…)//printf函数描述
int sprintf(char* string,char* format,变元1,变元2,…)//sprintf与printf一样,只是把结果保留在字符串string中,而不是作为标准输出
char* format 叫做格式化字符串,包括普通字符和格式转换规格说明
例如:printf(”this is the number i %3i\n”,i);其中每一个转换规格说明都从%开始,以一个转换字符结束,这两者中间可以加有一些说明成分
//格式化输出输入
#include<stdio.h>
int main()
{
char number[]="hello world";
printf("%s\n",number);//
printf("%-s\n",number);//负号表示左对齐输出
printf("%25s\n",number);//数字25表示最少占据的子宽为25,这样不加负号就会靠右
printf("%10.5s\n",number);//小数点用于分隔字宽和精度,5表示字符串最多打印5个字符,或者浮点数小数点后保留5位
}
结果如下:
格式化输入
int scanf(char* format,…(变元))//格式化输入函数形式,变元必须是指针
int sscanf(char* string,char* format,…)
char* format 叫做格式化字符串,包括普通字符和格式转换规格说明
格式化字符串可能出现的情况如下:
(1)空格或制表符,直接忽略
(2)普通字符,用于匹配输入流中下面尚待读入的非空白字符序列
(3)转换规格说明,由%开始,转换字符结束,中间可以有附加项
#include<stdio.h>
int main()
{
int day,year;
char name[10];
scanf("%d %d",&day,&year);
//两个%d之间的空格没有任何影响,读取输入时也将忽略空白符(空格,换行,制符表等)
printf("day is %i, year is %i\n",day,year);
//即最后输入31 2014与31换行2014结果是一样的
}
如果改成
scanf("%d haha %d",&day,&year);//可以看到如果我输入31 haha 2015 则正确输出,若是直接输入31 2015 则输出只能把31正确输出
结果如下
//scanf()小的注意点
int main()
{
char number;
scanf("%1s",&number);//表明忽略输入的空白符,即输入一个空白符不会给number
//scanf("%c",&number);//不忽略空白符
printf("%c\n",number);
}
scanf()给我的感觉就是,你要在”“这个里面有正确的格式,这样程序运行时,它会从输入流中一个个读取相应的数据给变元,遇到空字符要根据情况而定是不是读取这个空字符(一般是忽略的),最后如果正确读完就OK,发现有不对的数据格式,就停止。
//读取一个字符串遇到的问题
#include<stdio.h>
int main()
{
char* number;
scanf("%s",number);
printf("%s\n",number);
}//以下为程序运行出错,说segmentation fault,我大概理解为没有检查边界问题,指针改成字符数组就好了
以上都是操作系统给我们的标准输入,标准输出的接口,下面简单谈论一下之前讨论过的文件读取与写入相关内容
//读取文件内容
#include<stdio.h>
int main()
{
FILE* fp;//文件指针,FILE*类型定义在<stdio.h>中
int c;
fp=fopen("infile.txt","r");//fopen()返回FILE*类型
while((c=getc(fp))!=EOF)//getc(FILE*)返回文件中的下一个字符,遇到文件结束或错误,返回EOF
printf("%c",c);
printf("\n");
}
//这样一来,就可以如下定义,因为stdin就是标准输入指针,stdout就是标准输出指针
#define getchar() getc(stdin)
#define putchar(c) putc((c),stdout)
//从不同的文件中读取到标准输出,没有检查错误机制
#include<stdio.h>
void filecopy(FILE* ifp,FILE* tfp)//将ifp指向的文件内容复制到tfp指向的文件中去
{
char c;
while((c=getc(ifp))!=EOF)
putc(c,tfp);
}
int main(int argc,char* argv[])//采用可变参数类型
{
FILE* fp;
if(argc==1)
filecopy(stdin,stdout);
else
while(--argc>0)
{
fp=fopen(*++argv,"r");
filecopy(fp,stdout);
fclose(fp);
}
return 0;
}
行输入输出相关
char* fgets(char *line,int maxline,FILE* fp)
/*fgets函数从fp所指向的文件中读取下一个输入行(包括换行符,并将它放在字符数组line中,最多可以读取maxline-1个字符,所读取的行以空字符‘\0’结尾),正确时返回line,错误时返回NULL*/
对比gets()是在stdin上操作,且不包括换行符
int fputs(char* line,FILE* fp)
/*将字符串写入到文件中,若有错误返回EOF,没有则返回0*/
对比puts()是在stdout上操作,且添加一个换行符