声明:本系列学习笔记适合有一定c语言基础的朋友参考学习,全部以个人学习的经验总结出来。以著名《c程序设计语言》实例分析为主。
每日一语:运算顺序
= 是from right to left
&& || from left to right
第一个程序:
编写一个程序,将他的输入复制到输出,并将多个连续空格替换成为一个空格:
1 #include <stdio.h> 2 void main(){ 3 while(1){ 4 int i,j; 5 i=0;j=0; 6 char str[100]; 7 char cpy[100]; 8 printf("input string:\n"); 9 gets(str);//gets是标准输入输出函数,用来获取屏幕输入字符串 10 while(i<100) 11 { 12 if(str[i]!=' ') 13 { 14 cpy[j++] = str[i]; 15 i++; 16 } 17 else //多个连续空格替换成为一个空格 18 { 19 cpy[j++]=str[i]; 20 while(str[i] == ' ') //这个while循环是关键 21 i++; 22 } 23 24 } 25 printf("copying after:%s\n",cpy); 26 } 27 }
这里用数组限定了输入字符串的长度,这种代码编写的风格不适合体会与用户的交互的特点,下面对代码进行优化。
请看第二个程序:
1 #include <stdio.h> // 标准头文件 2 3 int main() 4 { 5 int c; 6 int flag = 1; // 是否第一个空格。 7 8 while ((c=getchar()) != EOF) 9 { 10 if ((c != ' ') || (flag != 0)) 11 { 12 putchar(c); 13 flag = (c != ' '); 14 } 15 } 16 17 return 0; 18 }
知识点:
字符输入/输出(文件复制):
标准库提供的输入/输出模型非常简单。无论文本从何处输入,输出到何处,其输入/输出都是按照字符流的方式处理。
标准库提供了一次读/写一个字符的函数,其中最简单的是getchar和putchar两个。每次调用是,getchar函数从文本流中读入下一个输入字符,并将其作为结果值返回。这种字符通常是通过键盘输入的。
1 /*************** 2 description: 3 字符输入/输出:文件复制 4 ***************/ 5 #include <stdio.h> 6 7 void main() 8 { 9 int c; 10 while((c=getchar())!=EOF) 11 putchar(c); 12 }
字符在键盘、屏幕或其他任何地方无论以什么形式表现,它在机器内部都是以位模式存储的。char类型专门用于存储这种字符型数据,当然任何整型(int)也可以用于存储字符型数据。至于为什么程序中变量c定义为int型,我们接下来慢慢讲。
如何区分文件中有效数据与输入结束符的,C语言采取的解决办法是:在没有输入时,getchar函数将返回一个特殊值,这个特殊值与任何实际字符都不同。这个值成为EOF(end of file)。我们在声明变量c的时候,必须让它大到足以存放getchar函数返回的任何值。
所以这里不把c声明成char类型,是因为它必须足够大,除了能存储任何可能的字符外还要能存储文件结束符EOF。因此,将c声明成int类型。
EOF定义在头文件<stdio.h>中,是一个整型数。其具体值是什么稍后看,但要知道它与任何char类型的值都不相同。
程序3:
1 //统计输入的空格 制表符 换行符 个数 2 3 int c,m,n,l; 4 m=n=l=0; 5 /* m代表空格个数,n代表制表符个数,l代表换行符个数 */ 6 int flag=0;//表示是否遇到换行符 7 while((c = getchar()) != EOF) 8 { 9 if(c == '\n') 10 { 11 ++l; 12 flag = 1; 13 continue; 14 } 15 else if(flag == 0) 16 { 17 if(c == ' ') 18 { 19 ++m; 20 } 21 if(c == '\t') 22 { 23 ++n; 24 } 25 } 26 } 27 printf("%d\t%d\t%d",m,n,l);
程序4:
单词计数:
在linux 程序中 wc是这样实现的:
1 #include<stdio.h> 2 3 4 #define IN 1 5 #define OUT 0 6 main() 7 { 8 int c,nl,nw,nc,state; 9 10 state = OUT; 11 nl = nw = nc = 0; 12 while ((c = getchar()) != EOF) //读字符 以ctrl + z结束输入?????? 13 { 14 ++nc; //字符数加一; 15 if (c == '\n' ) // 如果遇到 换行符 nl(行数)加一 16 ++nl; 17 18 19 if (c == ' ' || c == '\n' || c == '\t') //如果遇到空格,换行,制表符 说明一个字结束 20 state = OUT; //由state = out 表示一个 字 读完了 21 else if (state == OUT) //判断是不是刚读完一个字,只有在读入 后一个字的第一个字符时 state还是out,所以执行下面代码 22 { //其他时候state都是 in; 23 state = IN; //因为是在读下一个字的第一个字符所以state = in标记正在读一个字且没到结尾; 24 ++nw; //因为在读这个字符之前刚读了一个字,所以字数加一; 25 } 26 } 27 printf("%d %d %d\n", nl, nw, nc); 28 }
在vc6.0平台下 遇到一个问题,就是EOF 是不是 按回车代表结束符???在不同的平台下是不一样的??????
1 //问题程序? 2 #include <stdio.h> // 标准头文件 3 4 int main() 5 { 6 while(1) 7 { 8 int c; 9 while((c=getchar())!=EOF) 10 putchar(c);//输入转换为输出;成功 11 12 13 int nc; 14 while((c=getchar())!=EOF) 15 ++nc; 16 printf("统计输入字符个数:%d",nc);//统计字符输入个数 17 18 } 19 return 0; 20 }
如何终止文件流的输入呢??
Windows的控制台里面可以通过Ctrl + Z来通知系统达到了文件结束
Linux/Unix的Shell里面可以通过Ctrl + D来表示达到文件结束
那么EOF的值是多少呢??
#include <stdio.h> int main() { printf("%d\n",EOF); return 0; }
新手必备:关于EOF的知识,请看链接: