C码字练习.06.输入,输出,交互 - 北方连萌

C码字练习.06.输入,输出,交互

重定向输入输出

输入不一定是键盘
输出不一定是屏幕

它们都可以是文件

在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

添加新评论

电子邮件地址不会被公开,评论内容可能需要管理员审核后显示。