getchar
计算getchar输入
一、碰见个很烦的题目:
*对输入的行、单词和字符进行计数。我们将单词的定义进行化简,认为单词是不包含空格、制表符\t及换行符的字符序列。例如:“a+b+c”,认为是1个单词,它由5个字符组成。又如:“xy abc”,为2个单词,6个字符。输入ctrl+z结束(提示:用ch!=EOF或ch!=-1作为循环条件)。
**输出格式要求:”Lines=%d\nWords=%d\nChars=%d\n”
程序运行示例如下:
hi~
Good moring!
I’m Julie.
Lines=3
Words=5
Chars=28
二、代码实现:
我根本不会写啊,甚至连运行都运行不了。
1 | |
1,为什么 ch 要定义成 int 类型?我输入的不是字符吗?
你说得对!你输入的确实是「字符」(比如 h、i、\n),但 getchar() 这个函数的设计很特殊 —— 它返回的不是 char 类型,而是 int 类型。
核心原因:要区分「普通字符」和「结束信号 EOF」
- 计算机里的所有字符(包括字母、符号、换行符
\n),在底层都会被转换成一个 0~255 之间的整数(ASCII 码)。比如'a'对应 97,'\n'对应 10,空格' '对应 32。 - 而
EOF(你之前代码里的结束信号,输入Ctrl+Z触发),它的本质是一个 -1(整数),用来告诉程序 “输入已经结束了,别再读了”。
如果 ch 定义成 char 会出什么问题?
char 类型的范围很窄(多数编译器默认是 -128~127),它没法正确处理 EOF:
- 若
char是「有符号」的:虽然-1能存,但有些扩展 ASCII 字符(比如某些特殊符号)的编码也会是负数,可能和EOF混淆,导致程序提前退出或一直不退出; - 若
char是「无符号」的:-1会被强制转换成 255(相当于一个普通字符),程序永远认不出EOF,循环会无限执行,关都关不掉。
总结:
ch 定义成 int,是为了同时接收两种东西:
- 普通字符(本质是 0~255 的整数,存到
int里完全没问题); - 结束信号
EOF(本质是-1,只有int能正确识别,不会和普通字符混淆)。
你之前第一次写的代码用 char ch,其实是有隐藏 bug 的,只是没触发而已;改成 int ch 才是标准、安全的写法。
2.\t 是啥?
\t 是 C 语言里的「转义字符」,全称是「水平制表符」,作用和你键盘上的 Tab 键 完全一样 —— 就是在输出或输入时,插入一个 “制表位空格”(大概占 4~8 个普通空格的宽度,用来对齐文本)。
举个例子:
输入时:你在键盘上按一下 Tab 键,程序读取到的就是 \t;输出时:printf("姓名\t年龄\t性别\n"); 会打印成:
1 | |
结合你之前的题目:
题目说 “单词是不包含空格、制表符 \t 及换行符 \n 的字符序列”—— 意思是:\t 和空格、换行符一样,都是「单词的分隔符」。比如输入 hello\tworld(hello 和 world 之间按了 Tab 键),会被统计成 2 个单词,而不是 1 个。
三、EOF 和 -1 是什么鬼东西?
1. EOF 是什么?
- 全称:End Of File(文件结束符);
- 本质:它不是一个 “字符”,而是一个「信号」—— 告诉程序 “输入已经读完了,没有更多数据了”;
- 触发方式:在 Windows 系统下,你在控制台输入完内容后,按
Ctrl + Z(然后回车),就会向程序发送EOF信号;在 Linux/Mac 下是Ctrl + D。
2. EOF 和 -1 的关系?
EOF是 C 语言标准库(stdio.h)里定义的一个「宏」(可以理解成一个 “常量别名”);- 它的底层定义就是
#define EOF (-1)—— 所以EOF本质上就是整数-1; - 程序里写
ch != EOF和ch != -1效果完全一样,但写EOF更规范、更容易看懂(别人一看就知道是 “判断输入是否结束”)。
3. 为什么要用 EOF?
比如你之前的题目,要求 “输入 Ctrl+Z 结束”—— 程序怎么知道你按下了 Ctrl+Z?就是通过 EOF 信号。getchar() 读取到 EOF 后,会返回 -1(也就是 EOF),循环条件 (ch=getchar())!=EOF 就会不成立,循环退出,程序结束统计。
判断getchar
又碰见一个:
编写一个程序,判断输入的一行字符是否构成一个合法的C标识符(以下划线_或字母开头,由下划线、字母和数字组成视为合法的C标识符)。(假设输入的字符串非关键字且最大长度为32)
**输入格式要求:getchar()
**输出格式要求:”is\n” “is not\n”
程序运行示例1如下:
$223
is not
程序运行示例2如下:
hello world
is not
程序运行示例3如下:
hello
is
程序运行示例4如下:
a.net
is not
程序运行示例5如下:
123
is not
代码实现:
1 | |
看看AI写的:
1 | |
总结:
可以用数组储存getchar得到的东西