学习内容:c primer plus 的第八章字符输入/输出和输入验证。
重点内容:重定向,返回一个正确响应的函数,eof。
1.重定向
重定向:就是重新定义输入和输出。输入和输出不再是键盘了。而可以输入和输出都是文件。或者其中一个是文件
重定向实现条件:1.已经生成有可执行文件2.整个操作在cmd命令行上面操作。并且定位到可执行文件的位置3.文本文件放在与可执行文件一起的位置
重定向的基本格式
123(可执行文件名).exe < 数据文件名1.txt > 另一个数据文件名2.txt
这个命令给出做出一个1.txt的文件,并将命名为2.txt.
单独使用<
123(可执行文件名).exe < (数据文件名)1.txt
意思就是将1.txt 作为123.exe的输入流
单独使用>
(可执行文件名)123.exe > (数据文件名)2.txt
意思就是2.txt最为123.exe的输出流。
例子:你可以试一试这个程序作为将要生成exe文件的源程序文件。记得一定要看注意事项
#include <stdio.h>
int main(void)
{
//规定了ctrl z退出。大退出
int ch;
while((ch=getchar())!=EOF)
{
putchar(ch);
}
return 0;
}
2.返回一个正确响应的函数。(下面只是函数,具体实现你要调用)
2.1.只返回long类型的数。其他类型像字符就会被处理。
long get_long(void)//为什么不用issplace()函数,可能是因为没有反馈。
//但是我个人感觉如果不要反馈(就是你输错的字符的话),issplace()函数是真的好用
{
long input;
char ch ;
while(scanf("%ld",&input)!=1)
{
while((ch=getchar())!='\n')//这个循环就是处理
putchar(ch);
printf("这不是一个数字,请输入一个数字\n"); //打印的效果可以自己尝试一下
//打印的效果就是这个一堆字符不是数字,仅此而已;
printf("比如11,12.9996.等的数字\n");
}
return input;
}
2.2只返回一串首字母的函数。
char get_first(void)
{
char firc;
do
{
firc=getchar();
}while(isblank(firc));
while(getchar()!='\n')
continue;
return firc;
}
2.3只返回符合特殊要求的,且只返回float类型的数字
float getnznum(void)
{
float num;
char ch;
printf("请输入一个非0的数字\n");
scanf("%f",&num);
if(num==0)//在这里可以输入你要的特殊条件。比如现在这个例子就是非0
{
printf("我不是都说了不要0,请再次输入\n");
scanf("%f",&num);
}
while(scanf("%f",&num)!=1)
{
while((ch=getchar())!='\n')
{
putchar(ch);
printf("这不是一个数字\n");
printf("请重新输入数字\n");
}
}
return num;
}
3.EOF
EOF的概念:简单理解就是标志这文本结束的符号。
EOF的特点:不需要引用特殊的库函数,因为他就在stdio.h库中。处理对象基本是文本。
1.没有用EOF
#include <stdio.h>
int main(void)
{
char ch;
while((ch=getchar())!='#')
{
putchar(ch);
}
return 0;
}
2.用来EOF的
#include <stdio.h>
int main(void)
{
//规定了ctrl z退出。大退出
int ch;
while((ch=getchar())!=EOF)
{
putchar(ch);
}
return 0;
}
得到的一些重点思路和启发:
1.如果scanf()没有成功读取,就会将其留在输入队列中。这里要明确,输入实际上是字符流。可以使用getchar()函数逐字符地读取输入,甚至可以把这些想法都结合在一个函数中.
下面给出一个函数你可以理解一下
long get_long(void)//为什么不用issplace()函数,可能是因为没有反馈。
//但是我个人感觉如果不要反馈(就是你输错的字符的话),issplace()函数是真的好用
{
long input;
char ch ;
while(scanf("%ld",&input)!=1)
{
while((ch=getchar())!='\n')//这个循环就是处理
putchar(ch);
printf("这不是一个数字,请输入一个数字\n"); //打印的效果可以自己尝试一下
//打印的效果就是这个一堆字符不是数字,仅此而已;
printf("比如11,12.9996.等的数字\n");
}
return input;
}
习题练习:
8.编写一个程序,显示一个提供加法、减法、乘法、除法的菜单。获得用户选择的选项后,程序提示用户输入两个数字,然后执行用户刚才选择的操作。该程序只接受菜单提供的选项。程序使用float类型的变量存储用户输入的数字,如果用户输入失败,则允许再次输入。进行除法运算时,如果用户输入0作为第2个数(除数),程序应提示用户重新输入一个新值。
#include<stdio.h>
#include<ctype.h>
char get_first(void);
float getnum(void);
float getnznum(void);
int main(void)
{
int ch;
float number1,number2;
printf("请输入你的操作\n");
printf("a.加法 s.减法\n");
printf("m.乘法 d.除法\n");
printf("q.退出\n");
while((ch=get_first())!='q')
{
printf("请输入第一个数字\n");
number1=getnum();
printf("请输入第二个数字\n");
number2=getnum();
switch(ch)
{
case 'a':printf("%.2f\n",number1+number2);
break;
case 's':
printf("%.2f\n",number1-number2);
break;
case 'm':printf("%.2f\n",number1*number2);
break;
case 'd':
if(number2==0)
{
number2=getnznum();
printf("%.2f\n",number1*number2);
}
else
{
printf("%.2f\n",number1/number2);
}
break;
}
printf("请再次输入你的操作,按住q结束\n");
}//这个是while()循环结束
return 0;
}
char get_first(void)
{
char firc;
do
{
firc=getchar();
}while(isspace(firc));//第一次错误就是因为这个isblank()
while(getchar()!='\n')
continue;
return firc;
}
float getnum(void)
{
float num;
char ch;
while(scanf("%f",&num)!=1)
{
while((ch=getchar())!='\n')
{
putchar(ch);
printf("这不是一个数字\n");
printf("请重新输入数字\n");
}
}
return num;
}
float getnznum(void)
{
float num;
char ch;
printf("请输入一个非0的数字\n");
scanf("%f",&num);
if(num==0)//在这里可以输入你要的特殊条件。比如现在这个例子就是非0
{
printf("我不是都说了不要0,请再次输入\n");
scanf("%f",&num);
}
while(scanf("%f",&num)!=1)
{
while((ch=getchar())!='\n')
{
putchar(ch);
printf("这不是一个数字\n");
printf("请重新输入数字\n");
}
}
return num;
}
2.菜单浏览。
选项内容变了,但是本质一样。
#include <stdio.h>
char getchoice(void);
char getfirst(void);
void count(void);
int main(void)
{
int choice;
while((choice=getchoice())!='q')
{
switch(choice)
{
case 'a':
printf("寒假作业尽管发,写完了算我输\n");
break;
case 'b':printf("你觉得你是谁\n");
break;
case 'c':count();
break;
default:printf("你不会真的写完了吧\n");
break;
}
printf("恭喜你写完了\n");
}
printf("游戏结束\n");
return 0;
}
char getchoice(void)
{
int ch;
printf("请输入字母\n");
printf("a是一个选项,b是一个选项\n");
printf("c是一个选项,q是退出选项\n");
ch=getfirst();
while((ch<'a'||ch>'c')&&ch!='q')
{
printf("请输入选项要的字母\n");
ch=getfirst();
}
return ch;
}
char getfirst(void)
{
char firc;
firc=getchar();
while(getchar()!='\n')
{
continue;
}
return firc;
}
void count(void)
{
int k,i;
printf("请输入一个值,然后输出从1到这个数的遍历函数.输入\n");
k=getint();
for(i=1;i<=k;i++)
printf("%d\n",i);
while(getchar()!='\n')
continue;
}
int getint(void)
{
int l;
while(scanf("%d",&l)!=1)
{
printf("请你看清楚提示。让你输入数字\n");
}
return l;
}
3.为一个进行算术运算的函数提供整数,该函数计算特定范围内所有整数的平方和。程序限制了范围的上限是10000000,下限是-10000000。
#include<stdio.h>
#include <stdbool.h> //特定范围内的所有数的平方和
#include <ctype.h>
long get_long(void);
bool bad_limit(long start,long end,long small ,long high);
double squaresum(long a,long b);
int main(void)
{
const long min =-10000000;
const long max =+10000000;
long start,end;
double result;
printf("请输入这组数的下限\n");
start=get_long();
printf("请输入这组数的上限\n");
end=get_long();
while(start!=0&&end!=0)
{
if(bad_limit(start,end,min,max))
{
printf("请你再次尝试一遍\n");
}
else
{
result=squaresum(start,end);
printf("这组数的结果是%lf\n",result);
}
printf("请输入这组数的下限\n");
start=get_long();
printf("请输入这组数的上限\n");
end=get_long();
}
printf("程序结束了\n");
return 0;
}
long get_long(void)//为什么不用issplace()函数,可能是因为没有反馈。
//但是我个人感觉如果不要反馈(就是你输错的字符的话),issplace()函数是真的好用
{
long input;
char ch ;
while(scanf("%ld",&input)!=1)
{
while((ch=getchar())!='\n')//这个循环就是处理
putchar(ch);
printf("这不是一个数字,请输入一个数字\n"); //打印的效果可以自己尝试一下
//打印的效果就是这个一堆字符不是数字,仅此而已;
printf("比如11,12.9996.等的数字\n");
}
return input;
}
bool bad_limit(long start,long end,long small ,long high)
{
bool k=false;
if(start>end)
{
k=true;
printf("你输入的上限比下限小\n");
}
if(start<small || end<small)
{
k=true;
printf("输入的两个上下限比设置的最小数还要小\n");
}
if(start>high || end>high)
{
k=true;
printf("输入的两个上下限比设置的最小数还要小\n");
}
return k;
}
double squaresum(long a,long b)
{
long i;
double result;
for(i=a,result=0;i<=b;i++)
{
result=result+(double)i*(double)i;
}
return result;
}