重定向输入输出
输入不一定是键盘
输出不一定是屏幕
它们都可以是文件
在h.exe的同一目录下生成output.txt
将以下代码编译成h.exe
#include<stdio.h>
int main(void)
{
int ch;
while((ch = getchar()) != EOF) //EOF == End of file(文件尾,值为-1)
putchar(ch);
return 0;
}
用命令提示符打开h.exe所在目录
输入以下内容
h>output.txt //"<"和">"都是重定向运算符,前者是输入重定向,后者是输出重定向
之后输入想要保存在文本文档中的内容,并换行按Ctrl+Z(表示文件尾,屏幕上会显示为^Z)再次换行结束程序
此时保存了输入内容的output.txt在同一目录下被生成
统计output.txt的字符数并保存到文件chnum.txt
当更换以上的代码时,我们就可以保存更多种的输出结果,而不仅仅是保存输入的字符本身
比如调整之前的统计字符数程序,把STOP的定义更改为文件尾,使程序能统计文本文档的字符数并输出至另一个文本文档
现在新编译以下代码为h1.exe
#include<stdio.h>
#define STOP EOF
int main(void)
{
char ch;
int ch_ct = 0, r_ct = 0, sp_ct = 0, sr_ct = 0;
while((ch = getchar()) != STOP)
{
ch_ct++;
if(ch == '\n')
{
r_ct++;
}
if(ch == ' ')
{
sp_ct++;
}
}
printf("There are %d character(s), %d space(s), and %d row(s) in output.txt.\n", ch_ct - sp_ct - r_ct, sp_ct, r_ct);
return 0;
}
命令提示符中输入
h1<output.txt>chnum.txt //这里有一个输入重定向和一个输出重定向,两者顺序可调换,执行时必先入再出
故这种样式也可
h1>chnum.txt<output.txt
随后同一目录下会生成一个chnum.txt文件,保存字数统计程序的输出结果
需注意输入输出的文件名不要相同,也不要复数次使用重定向,更不要对程序同士或文本同士使用重定向
实际上,对此代码编译的h.exe和一个文本文档text.txt
#include<stdio.h>
int main(void)
{
int ch;
while((ch = getchar()) != EOF) //EOF == End of file(文件尾,值为-1)
putchar(ch);
return 0;
}
使用
h1<output.txt>output(1).txt
即可在同一文件夹下创建一个副本
打印控制字符(脱出字符表示法)
ASCII码0到31为控制字符,一般在程序运行时是不显示的
脱出字符表示法即利用控制字符的十进制编码加64等于某些大写字母和符号,达到以^I(键盘输入为Ctrl + I)来表示制表符\t的效果
本程序中其他字符及空格照原样/脱出字符输出,^I及^J输出为\t及\n
#include<stdio.h>
int main(void)
{
int ch, c = 0;
printf("Please enter some characters (ASCII). Program will show these characters with their ASCII values.\n");
printf("(Press Ctrl+Z to terminate.)\n");
while ((ch = getchar()) != EOF)
{
if (ch == 9)
{
printf("\\t(%3d) ", ch + 64, ch);
}
else if (ch == 10)
{
printf("\\n(%3d) \n", ch + 64, ch);
}
else if (ch >= 0 && ch <=31)
{
printf("^%c(%3d) ", ch + 64, ch);
}
else
{
printf("%2c(%3d) ", ch, ch);
}
if(++c % 10 == 0)
{
putchar('\n');
}
}
printf("Bye.\n");
return 0;
}
Please enter some characters (ASCII). Program will show these characters with their ASCII value.
(Press Ctrl+Z to terminate.)
^K^K^K^K^K^K^K ^U^U^U$%^&*(??? UYFFYG
^K( 11) ^K( 11) ^K( 11) ^K( 11) ^K( 11) ^K( 11) ^K( 11) \t( 73) \t( 73) \t( 73)
^U( 21) ^U( 21) ^U( 21) $( 36) %( 37) ^( 94) &( 38) *( 42) (( 40) ?( 63)
?( 63) ?( 63) ( 32) ( 32) ( 32) ( 32) U( 85) Y( 89) F( 70) F( 70)
Y( 89) G( 71) \n( 74) //最后多一个/n被表示说明回车键同时充当换行键与被存进缓冲区
???? kkk p
?( 63) ?( 63) ?( 63) ?( 63) \t( 73) \t( 73) k(107) //这里另起一行只有7个元素是因为被之前的换行符中途换行了
k(107) k(107) ( 32) ( 32) p(112) \n( 74)
^Z //表示文件尾
Bye.
统计大小写字母
#include<stdio.h>
#include<ctype.h>
int main(void)
{
int cup = 0, cdo = 0;
char ch;
printf("Please enter some phrases.\n");
while ((ch = getchar()) != EOF)
{
if (isupper(ch))
cup++;
else if (islower(ch))
cdo++;
}
printf("You entered %d upperccases and %d lowercases.\n", cup, cdo);
return 0;
}
Please enter some phrases.
yOU RRRR SSSOOO BeauTIful.123
OOHHHHHHHHHhhhh
^Z
You entered 26 upperccases and 11 lowercases.
平均字母数统计
字母数 = 总字符数 - 空白字符数 - 标点数
单词数算法需要用到布尔变量
初始量设为伪,读取第一个字母非空格,设为真,将单词数也加一
直到读到单词直后的空格,再次设为伪,准备统计下一个单词
#include<stdio.h>
#include<ctype.h>
#include<stdbool.h>
int main(void)
{
bool inword = false;
int ch, cw = 0, c = 0, cs = 0, cp = 0;
printf("Please enter some phrases.\n");
while ((ch = getchar()) != EOF)
{
//统计单词数
if (!isspace(ch) && !inword)
{
inword = true;
cw++;
}
if (isspace(ch) && inword)
inword = false;
//统计字母,空格和标点数
c++;
if(isspace(ch))
cs++;
if(ispunct(ch))
cp++;
}
printf("There are %.2f letter(s) for each word in average in phrases you entered.\n", (c - cs - cp) / (double)cw);
return 0;
Please enter some phrases.
Bie wen wo shi shei.
Qing yu wo xiang lian.
^Z
There are 3.20 letter(s) for each word in average in phrases you entered.
二分法猜数字
输入上下限,让程序在其中猜数字,用户可以提示程序猜的是大是小还是正好直到猜中
基本版
#include<stdio.h>
#include<ctype.h>
void binary(int min, int max, int u, int l);
int main(void)
{
int u, l, i, max, min;
double minxx, maxxx;
printf("Please enter 2 numbers greater than 0.\n");
printf("(For decimals, decimal parts will be cut automatically.)\n");
b:
//判断输入的是否是数字
printf("min = ");
while (scanf("%lf", &minxx) != 1 || minxx <= 0)
{
printf("I only recognize numbers greater than 0.\n");
printf("min = ");
while (getchar() != '\n')
{
continue;
}
}
min = (int)minxx;
printf("max = ");
while (scanf("%lf", &maxxx) != 1 || maxxx <= 0)
{
printf("I only recognize numbers greater than 0.\n");
printf("max = ");
while (getchar() != '\n')
{
continue;
}
}
max = (int)maxxx;
//判断上下限的要求是否符合
if (max <= min +1)
{
printf("max must be greater than min + 1. Please retry.\n");
goto b;
}
else
{
printf("Let me guess a number between %d & %d (excluding min & max).\n", min, max);
//上下限中间只有1个数时可直接判断
i = (min + max) / 2;
if (i == min + 1)
{
printf("It has to be %d!\n", i);
printf("Done.\n");
}
else
{
u = max;
l = min;
binary(min, max, u, l);
}
}
return 0;
}
void binary(int min, int max, int u, int l)
{
char ch, c1;
int c = 0, i;
printf("Is it %d?\n", (min + max) / 2);
printf("------------------------------------\n");
printf("a) too small b) too big c) bingo\n");
printf("------------------------------------\n");
while (max > min + 1)
{
a:
//清除上一次循环中的多余的字符
while (getchar() != '\n')
{
continue;
}
scanf("%c", &ch);
//防止不停地在两个相邻的数之间跳
if ((c1 == 'a' && ch == 'b' && i == min + 1) || (c1 == 'b' && ch == 'a' && i == min - 1))
{
printf("Don't play with me!\n");
break;
}
//判断是否触及上下限
if (i == u - 2 && ch == 'a')
{
printf("It has to be %d!\n", u - 1);
break;
}
if (i == l + 2 && ch =='b')
{
printf("It has to be %d!\n", l + 1);
break;
}
if ((i == u - 1 && ch == 'a') || (i == l + 1 && ch =='b'))
{
printf("There is no other way.\n");
break;
}
//设置选项输入限制
if (ch == 'a')
{
min = (min + max) / 2;
c1 = ch;
}
else if (ch == 'b')
{
max = (min + max) / 2;
c1 = ch;
}
else if (ch == 'c')
{
break;
}
else if (ch != 'a' || ch != 'b' || ch != 'c')
{
printf("Please enter a,b or c.\n");
goto a;
}
i = (min + max) / 2;
printf("Is it %d?\n", i);
printf("------------------------------------\n");
printf("a) too small b) too big c) bingo\n");
printf("------------------------------------\n");
}
printf("Done.\n");
}
交互性:
(1)上下限设定阶段
上下限只限输入正数
上限不得低于下限且上下限之间必须至少间隔一个数字
上下限之间正好间隔一个数字则直接输出此间隔数字
Please enter 2 numbers greater than 0.
(For decimals, decimal parts will be cut automatically.)
min = a
I only recognize numbers greater than 0.
min = -7
I only recognize numbers greater than 0.
min = 1
max = -7
I only recognize numbers greater than 0.
max = 1.55
max must be greater than min + 1. Please retry.
min = 1.55
max = 3
Let me guess a number between 1 & 3 (excluding min & max).
It has to be 2!
Done.
(2)判断阶段
选项仅限输入a,b,c
若猜测进行到距离上限仅间隔一个数字则直接输出此间隔数字(逼近下限时同理)
Please enter 2 numbers greater than 0.
(For decimals, decimal parts will be cut automatically.)
min = 1
max = 20
Let me guess a number between 1 & 20 (excluding min & max).
Is it 10?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
6
Please enter a,b or c.
q
Please enter a,b or c.
a
Is it 15?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
a
Is it 17?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
a
Is it 18?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
a
It has to be 19!
Done.
(3)Don't play with me!
Please enter 2 numbers greater than 0.
(For decimals, decimal parts will be cut automatically.)
min = 10
max = 20
Let me guess a number between 10 & 20 (excluding min & max).
Is it 15?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
a
Is it 17?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
a
Is it 18?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
b
Don't play with me!
Done.
(4)There is no other way.
Please enter 2 numbers greater than 0.
(For decimals, decimal parts will be cut automatically.)
min = 444
max = 4454
Let me guess a number between 444 & 4454 (excluding min & max).
Is it 2449?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
b
Is it 1446?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
b
Is it 945?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
b
Is it 694?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
b
Is it 569?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
b
Is it 506?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
b
Is it 475?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
b
Is it 459?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
b
Is it 451?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
b
Is it 447?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
b
Is it 445?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
b
There is no other way.
Done.
正常示例:猜测数字99
Please enter 2 numbers greater than 0.
(For decimals, decimal parts will be cut automatically.)
min = 40
max = 161
Let me guess a number between 40 & 161 (excluding min & max).
Is it 100?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
b
Is it 70?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
a
Is it 85?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
a
Is it 92?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
a
Is it 96?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
a
Is it 98?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
a
Is it 99?
------------------------------------
a) too small b) too big c) bingo
------------------------------------
c
Done.
微调版
减少了一个goto
#include<stdio.h>
#include<ctype.h>
void binary(int min, int max, int u, int l);
int main(void)
{
int u, l, i, max, min;
double minxx, maxxx;
printf("Please enter 2 numbers greater than 0.\n");
printf("(For decimals, decimal parts will be cut automatically.)\n");
b:
//判断输入的是否是数字
printf("min = ");
while (scanf("%lf", &minxx) != 1 || minxx <= 0)
{
printf("I only recognize numbers greater than 0.\n");
printf("min = ");
while (getchar() != '\n')
{
continue;
}
}
min = (int)minxx;
printf("max = ");
while (scanf("%lf", &maxxx) != 1 || maxxx <= 0)
{
printf("I only recognize numbers greater than 0.\n");
printf("max = ");
while (getchar() != '\n')
{
continue;
}
}
max = (int)maxxx;
//判断上下限的要求是否符合
if (max <= min +1)
{
printf("max must be greater than min + 1. Please retry.\n");
goto b;
}
else
{
printf("Let me guess a number between %d & %d (excluding min & max).\n", min, max);
//上下限中间只有1个数时可直接判断
i = (min + max) / 2;
if (i == min + 1)
{
printf("It has to be %d!\n", i);
printf("Done.\n");
}
else
{
u = max;
l = min;
binary(min, max, u, l);
}
}
return 0;
}
void binary(int min, int max, int u, int l)
{
char ch, c1;
int c = 0, i;
printf("Is it %d?\n", (min + max) / 2);
printf("------------------------------------\n");
printf("a) too small b) too big c) bingo\n");
printf("------------------------------------\n");
while (max > min + 1)
{
//清除上一次循环中的多余的字符
while (!isspace(getchar()))
{
continue;
}
ch = getchar();
//防止不停地在两个相邻的数之间跳
if ((c1 == 'a' && ch == 'b' && i == min + 1) || (c1 == 'b' && ch == 'a' && i == min - 1))
{
printf("Don't play with me!\n");
break;
}
//判断是否触及上下限
if (i == u - 2 && ch == 'a')
{
printf("It has to be %d!\n", u - 1);
break;
}
if (i == l + 2 && ch =='b')
{
printf("It has to be %d!\n", l + 1);
break;
}
if ((i == u - 1 && ch == 'a') || (i == l + 1 && ch =='b'))
{
printf("There is no other way.\n");
break;
}
//设置选项输入限制
if (ch == 'a')
{
min = (min + max) / 2;
c1 = ch;
}
else if (ch == 'b')
{
max = (min + max) / 2;
c1 = ch;
}
else if (ch == 'c')
{
break;
}
else if (ch != 'a' || ch != 'b' || ch != 'c')
{
printf("Please enter a,b or c.\n");
continue;
}
i = (min + max) / 2;
printf("Is it %d?\n", i);
printf("------------------------------------\n");
printf("a) too small b) too big c) bingo\n");
printf("------------------------------------\n");
}
printf("Done.\n");
}
输出首个非空白字符
#include<stdio.h>
#include<ctype.h>
char get_first(void);
int main(void)
{
char ch;
while (isspace(ch = getchar()))
{
continue;
}
printf("Result:\n%c\n", ch);
return 0;
}
a
Result:
a