什么是 isspace?
isspace 是 C 标准库中的一个函数,用于检查一个字符是否是空白字符。
- 所属头文件:
#include <ctype.h> - 函数原型:
int isspace(int c); - 返回值:
c是一个空白字符,返回非零值(通常是1或true)。c不是空白字符,返回0(或false)。
什么是空白字符?
isspace 函数识别的“空白字符”不仅仅是空格,根据 C 标准(如 C99, C11),以下字符都被认为是空白字符:
| 字符 | 十进制 ASCII 值 | 名称 | 描述 |
|---|---|---|---|
| ` ` | 32 | 空格 | 最常见的空白字符。 |
\t |
9 | 水平制表符 | 用于对齐文本。 |
\n |
10 | 换行符 | 移动到下一行开头。 |
\v |
11 | 垂直制表符 | 垂直方向对齐(不常用)。 |
\f |
12 | 换页符 | 用于控制打印机分页。 |
\r |
13 | 回车符 | 移动到当前行开头(常与 \n 组合使用)。 |
函数原型中的 int c 为什么是 int?
这是一个 C 语言库函数的常见设计模式,虽然我们通常用一个 char 类型的字符去调用它,但函数的参数被声明为 int,这样做的原因主要有两个:
- 可以安全地传递所有
char值:char类型可能是signed(有符号)或unsigned(无符号)。char是有符号的,并且值为负(某些字符编码可能产生负值),直接传给int会进行符号扩展,可能导致意外行为,而int可以容纳所有char的值。 - 可以传递一个特殊的“结束”标记:这是更重要的原因,库函数允许你传递一个
EOF(End-Of-File,值为 -1)作为参数,当isspace收到EOF时,会直接返回 0,因为EOF不是一个字符,这使得在循环中检查字符和文件结束状态变得非常方便和高效。
示例用法:
#include <stdio.h>
#include <ctype.h>
int main() {
char c1 = ' ';
char c2 = 'A';
char c3 = '\t';
int c4 = EOF; // End-Of-File
printf("'%c' is a space? %d\n", c1, isspace(c1)); // 输出: 1
printf("'%c' is a space? %d\n", c2, isspace(c2)); // 输出: 0
printf("'%c' is a space? %d\n", c3, isspace(c3)); // 输出: 1
printf("EOF is a space? %d\n", isspace(c4)); // 输出: 0
return 0;
}
常见应用场景
isspace 最常见的用途是跳过字符串开头的空白字符,例如在解析用户输入时。
场景1:跳过前导空白
#include <stdio.h>
#include <ctype.h>
void skip_leading_whitespace(const char *str) {
// 检查指针是否为 NULL
if (str == NULL) {
return;
}
// 只要当前字符不是字符串结尾 ('\0') 并且是空白字符,就移动指针
while (*str != '\0' && isspace(*str)) {
str++;
}
// str 指向第一个非空白字符,或者字符串末尾
printf("The first non-whitespace character is: '%c'\n", *str);
}
int main() {
char input1[] = " Hello, World!";
char input2[] = "12345";
char input3[] = " \t\n\v\rStart here";
skip_leading_whitespace(input1); // 输出: 'H'
skip_leading_whitespace(input2); // 输出: '1'
skip_leading_whitespace(input3); // 输出: 'S'
return 0;
}
场景2:统计一行中的单词数量
这是一个经典的面试题,算法思路是:当遇到一个非空白字符时,表示一个单词开始,然后跳过这个单词直到遇到下一个空白字符。
#include <stdio.h>
#include <ctype.h>
int count_words(const char *str) {
if (str == NULL) {
return 0;
}
int in_word = 0; // 标记当前是否在单词内部
int word_count = 0;
while (*str != '\0') {
if (isspace(*str)) {
// 如果遇到空白,并且之前在单词里,说明单词结束了
if (in_word) {
word_count++;
in_word = 0;
}
} else {
// 如果遇到非空白,标记为在单词里
in_word = 1;
}
str++; // 移动到下一个字符
}
// 循环结束后,如果最后一个字符是单词的一部分,需要计数
if (in_word) {
word_count++;
}
return word_count;
}
int main() {
char text1[] = "This is a simple sentence.";
char text2[] = " Hello, world! ";
char text3[] = "NoSpaces";
printf("'%s' has %d words.\n", text1, count_words(text1)); // 输出: 5
printf("'%s' has %d words.\n", text2, count_words(text2)); // 输出: 2
printf("'%s' has %d words.\n", text3, count_words(text3)); // 输出: 1
return 0;
}
与 isblank 的区别
还有一个相关的函数叫 isblank,也定义在 <ctype.h> 中。
isspace: 检查所有 6 种空白字符 (`,\t\n\v\f\r`)。isblank: 只检查两种空白字符:空格 (` `) 和水平制表符 (\t)。
isblank 是 C99 标准引入的,它的定义更严格,只关心那些在文本中产生“水平空白”的字符。
- 如果你需要跳过所有用于格式化、分行的空白,使用
isspace。 - 如果你只想跳过空格和制表符(处理某些特定的数据格式),使用
isblank。
在大多数通用场景下,isspace 是更常用的选择。
