在程序设计中,很重要的处理对象就是字符,把多个字符放在一起,就是字符数组;在字符数组尾部添个标记,就成了字符串。
除了数字,在C语言中还有一个重要的类型就是字符。对于一个新的类型,需要掌握它的定义、输入和输出。
通过下面的程序,你就可以了解到字符是如何输入输出的了。
1 2 3 4 5 6 7 8 9 10 11 | #include <stdio.h> int main(int argc, char *argv[]) { char c1, c2; c1 = getchar(); scanf("%c", &c2); putchar(c1); printf("%c\n", c2); return 0; } |
在处理字符输入时,通常采用函数 getchar,当然也可以采用scanf。getchar 可以读入任何字符,包括空格、换行和很多不可见字符,而 scanf 通常用来读入规整的整数据类型,这些类型用空格分开。
字符输出时,既可以使用 printf,也可以使用 putchar。使用 printf 输出单个字符,感觉有点杀鸡用牛刀。从程序效率上来说,当然 putchar的效率要远远高于printf。在生活中,我们也有体会。如果仅仅是打电话,那么买个Nokia N1280就够了;如果要功能超强的,苹果是不错的选择,但价格就远远高于N1280了。
![]() |
![]() |
其实对于计算机来说,并没有字符和数字的区分,保存在机器中的都是0和1的组合,只是在输出时会区别对待,实时运行下面的例子。
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <stdio.h> int main(int argc, char *argv[]) { char c; c = 'A'; putchar(c); printf("%c\n", c); printf("%d\n", c); printf("%o\n", c); printf("%x\n", c); return 0; } |
程序输出
1 2 3 4 | AA 65 101 41 |
在计算机中,最简单也是最基本的编码就是ASCII,全称美国信息交换标准代码。7位字符集广泛用于代表标准美国键盘上的字符或符号。通过将这些字符使用的值标准化,ASCII允许计算机和计算机程序交换信息。
在C-Free中,按 F1 获得帮助,点击内容(Content)中的“C++语言参考”,可以找到ASCII 码表。你可以找到字符A在不同进制下的数字表示。
试试下面的程序,看看输出什么?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #include <stdio.h> int main(int argc, char *argv[]) { int c; c = 65; putchar(c); printf("%c\n", c); printf("%d\n", c); printf("%o\n", c); printf("%x\n", c); putchar(c); putchar(c+1); putchar(c+2); printf("\n"); return 0; } |
根据ASCII,可以很轻松的编写将小写字母转换成大写字母,或者反过来。 下面的例子展现了如何将大写字母转换成小写字母。
1 2 3 4 5 6 7 8 9 10 | #include <stdio.h> int main(int argc, char *argv[]) { char c; c = 'H'; putchar(c+'a'-'A'); putchar('\n'); return 0; } |
注意: \n 被认为是一个字符而不是两个字符,在 putchar 中字符一律使用单引号。'a'-'A' 可以认为是小写字母和大写字母之间的距离,通过调整距离,就完成了大小写之间的转换。
大小写转换是常用的功能,在C语言的库函数中已经实现了。要使用islower() 函数,别忘了在程序的预处理部分加上
1 | #include <ctype.h> |
在这个库中,还有很多有用的函数,值得好好研究。
接下来,我们研究由很多字符组成的一个文件。
键盘输入也成为标准输入(Standard Input),这些输入也被理解为一个文件。
EOF(End Of File)表示文件结束符,其值是-1。在文本文件中,数据都是以字符的ASCII代码值的形式存放。我们知道,ASCII代码值的范围是0~255,不可能出现-1,因此可以用EOF作为文件结束标志。
如何通过键盘输入EOF? 在 UNIX中, EOF能从交互式 shell (终端) 送出 Ctrl+D (习惯性标准);在微软的 DOS 与 Windows 中能送出 Ctrl+Z。
下面的程序统计文件中出现了多少个字符。
1 2 3 4 5 6 7 8 9 10 11 | #include <stdio.h> int main(int argc, char *argv[]) { char c; int count = 0; while ( (c = getchar() ) !=EOF) count++; printf("%d\n", count ); return 0; } |
1 2 3 4 5 6 | Find Your Greatness ^Z 20 Press any key to continue |
把赋值和读取合并在一起,可以得到如下更为简练的的代码(只显示了计算部分的代码):
1 2 | while ( (c = getchar() ) !=EOF) count++; |
用如此简练的代码实现了很有用的功能,这也是C语言的魅力所在。
while循环和for循环可以相互转换,用 for循环写就是:
1 2 | for (c = getchar() ; c !=EOF ; c = getchar() ) count++; |
把赋值和读取合并在一起,就是
1 2 | for ( ; (c = getchar() ) !=EOF ; ) count++; |
更加一般的, for 循环和 while循环的相互转换如下所示:
1 2 3 | for (表达式1; 表达式2 ; 表达式3) { 若干条语句 ; } |
1 2 3 4 5 | 表达式1; while (表达式2) { 若干条语句 ; 表达式3; } |
下面的代码经常会用到:
1 2 | while ( (c = getchar() ) !=EOF) count++; |
假设要求从文件中读取一些整数,每行两个,计算这两个整数数的和并输出,每行一个,那么可以编写出下面的代码
1 2 3 4 5 6 7 8 9 10 | #include <stdio.h> int main(int argc, char *argv[]) { int a, b; while (scanf("%d%d", &a, &b)!=EOF) { printf("%d\n", a+b); } return 0; } |
如果你去查看一下 scanf 函数原型,会发现返回值的类型不是 void,而是 int,返回数的含义是正确读到的数的个数,在本题中返回2。 当 scanf 遇到 EOF时,就返回EOF,也就是 -1。