字符函数大部分都定义在
<ctype.h>头文件中 在C语言中,字符是以其对应的ASCII码(整数)存储的。例如,字符A的ASCII码是65,a是97,0是48。字符函数本质上就是对传入的整数值(字符)进行判断或运算
这些函数用于检查一个字符是否属于特定的类型。它们接收一个
int类型的参数(字符的ASCII码),返回一个int类型的值:非零(真)或 零(假)
函数名 | 功能描述 | 包含范围 | 示例 |
|---|---|---|---|
iscntrl | 检查字符是否为控制字符 | ASCII码 0~31 和 127 (DEL) | iscntrl('\n') → 真iscntrl('a') → 假 |
isspace | 检查字符是否为空白字符 | 空格' '、换页\f、换行\n、回车\r、水平制表符\t、垂直制表符\v | isspace(' ') → 真isspace('A') → 假 |
isdigit | 检查字符是否为十进制数字 | '0' ~ '9' | isdigit('5') → 真isdigit('a') → 假 |
isxdigit | 检查字符是否为十六进制数字 | '0'`‘9’`、`‘a’`'f'、'A'~'F' | isxdigit('a') → 真isxdigit('G') → 假 |
islower | 检查字符是否为小写字母 | 'a' ~ 'z' | islower('g') → 真islower('G') → 假 |
isupper | 检查字符是否为大写字母 | 'A' ~ 'Z' | isupper('X') → 真isupper('x') → 假 |
isalpha | 检查字符是否为字母 | 'a'~'z' 和 'A'~'Z' | isalpha('K') → 真isalpha('2') → 假 |
isalnum | 检查字符是否为字母或数字 | 'a'`‘z’`、`‘A’`'Z'、'0'~'9' | isalnum('B') → 真isalnum('!') → 假 |
ispunct | 检查字符是否为标点符号 | 任何不属于字母数字的可打印图形字符! " # $ % & ' ( ) * + , - . / : ; < = > ? @ [ \ ] ^ _ \ { | } ~` | ispunct('!') → 真ispunct(' ') → 假 |
isgraph | 检查字符是否为图形字符 | 所有可打印字符(不包括空格) | isgraph('A') → 真isgraph(' ') → 假 |
isprint | 检查字符是否为可打印字符 | 所有图形字符 + 空格' ' | isprint('A') → 真isprint('\n') → 假 |
通过从小写字母中减去 32 将字符串转换为大写
转换原理: 在ASCII码中,小写字母比对应的大写字母正好大32
#include <stdio.h>
#include <ctype.h>
int main()
{
int i = 0;
char str[] = "Test String.\n";
char c;
while (str[i])
{
c = str[i];
if (islower(c))
c -= 32;
putchar(c);
i++;
}
return 0;
}我们只需要学习前两种大小写转换函数,后面的我们作了解即可
C语言提供了2个字符转换函数:
int tolower ( int c ); //将参数传进去的⼤写字⺟转⼩写
int toupper ( int c ); //将参数传进去的⼩写字⺟转⼤写#include <stdio.h>
#include <ctype.h>
int main()
{
int i = 0;
char str[] = "Test String.\n";
char c;
while (str[i])
{
c = str[i];
if (islower(c)) {
c = toupper(c);
}
putchar(c);
i++;
}
return 0;
}#include <stdio.h>
#include <ctype.h>
int main() {
char ch1 = 'a', ch2 = 'B', ch3 = '5';
printf("'%c' 转换为大写: '%c'\n", ch1, toupper(ch1));
printf("'%c' 转换为小写: '%c'\n", ch2, tolower(ch2));
printf("'%c' 转换: '%c'\n", ch3, toupper(ch3)); // 数字不变
return 0;
}字符 ↔ 数字 一般情况下我们都会采取==+'0’或者-‘0’==来转换 下面我们介绍几种字符转换函数
#include <stdio.h>
#include <stdlib.h>
int main() {
char str1[] = "123";
char str2[] = "45.67";
char str3[] = "abc123";
printf("'%s' -> %d\n", str1, atoi(str1)); // 123
printf("'%s' -> %d\n", str2, atoi(str2)); // 45(遇到非数字停止)
printf("'%s' -> %d\n", str3, atoi(str3)); // 0(开头非数字)
return 0;
}atof() – 字符串转浮点数atol() – 字符串转长整数#include <stdio.h>
#include <stdlib.h>
int main() {
char buffer[20];
// 十进制
itoa(12345, buffer, 10);
printf("十进制: %s\n", buffer); // "12345"
// 二进制
itoa(10, buffer, 2);
printf("二进制: %s\n", buffer); // "1010"
// 十六进制
itoa(255, buffer, 16);
printf("十六进制: %s\n", buffer); // "ff"
return 0;
}#include <stdio.h>
int main() {
char buffer[100];
int integer = 123;
float floating = 45.67;
double double_num = 89.123456;
// 整数转字符串
sprintf(buffer, "%d", integer);
printf("整数: %s\n", buffer); // "123"
// 浮点数转字符串
sprintf(buffer, "%.2f", floating);
printf("浮点数: %s\n", buffer); // "45.67"
// 多种数据类型组合
sprintf(buffer, "整数:%d, 浮点数:%.3f", integer, double_num);
printf("组合: %s\n", buffer); // "整数:123, 浮点数:89.123"
// 不同进制转换
sprintf(buffer, "十进制:%d, 十六进制:%x, 八进制:%o", 255, 255, 255);
printf("进制: %s\n", buffer); // "十进制:255, 十六进制:ff, 八进制:377"
return 0;
}使用前记得添加头文件
#include <string.h> // 字符串函数
#include <stdio.h> // 输入输出char str[] = "hello";
int len = strlen(str); // len = 5#include <string.h>
char *strcpy(char *dest, const char *src);char src[] = "hello";
char dest[10];
strcpy(dest, src); // dest = "hello"在VS中好像会出现安全性问题,这时候我们可以添加宏定义
#define _CRT_SECURE_NO_WARNINGS#include <string.h>
char *strncpy(char *dest, const char *src, size_t n);#include <stdio.h>
#include <string.h>
int main() {
char src[] = "Hello World";
char dest[10];
// 安全复制,留一个位置给 \0
strncpy(dest, src, sizeof(dest) - 1);
dest[sizeof(dest) - 1] = '\0'; // 手动添加终止符
printf("安全复制: %s\n", dest); // Hello Wor
return 0;
}char * strcat ( char * destination, const char * source );source指向的源字符串中的所有字符都追加到destination指向的空间
中。destination :指针,指向⽬的地空间
source :指针,指向源头数据strcat 函数返回的⽬标空间的起始地址char str[20] = "Hello";
strcat(str, " World"); // "Hello World"
strncat(str, "!!!", 2); // "Hello World!!"int strcmp ( const char * str1, const char * str2 );str1和str2指向的字符串,从两个字符串的第⼀个字符开始⽐较,如果两个字符
的ASCII码值相等,就⽐较下⼀个字符。直到遇到不相等的两个字符,或者字符串结束。
参数:
str1 :指针,指向要⽐较的第⼀个字符串
str2 :指针,指向要⽐较的第⼆个字符串#include <stdio.h>
#include <string.h>
int main() {
char password[] = "secret123";
char input[50];
printf("请输入密码: ");
scanf("%49s", input);
if (strcmp(input, password) == 0) {
printf("密码正确!\n");
} else {
printf("密码错误!\n");
}
// 字符串排序判断
char name1[] = "John";
char name2[] = "Alice";
if (strcmp(name1, name2) < 0) {
printf("'%s' 在 '%s' 之前\n", name1, name2); // 不会执行
} else {
printf("'%s' 在 '%s' 之后\n", name1, name2); // 会执行
}
return 0;
}#include <string.h>
int strncmp(const char *str1, const char *str2, size_t n);#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "apple pie";
char str2[] = "apple cake";
// 只比较前5个字符
int result = strncmp(str1, str2, 5);
printf("前5字符比较: %d\n", result); // 0(相同)
// 比较前8个字符
result = strncmp(str1, str2, 8);
printf("前8字符比较: %d\n", result); // 1(不同)
return 0;
}char * strstr ( const char * str1, const char * str2);strstr 的使⽤得包含<string.h>
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="This is a simple string";
char * pch;
pch = strstr (str,"simple");
if (pch != NULL)
printf("%s\n", pch);
else
printf("查找的字符串不存在\n");
return 0;
}#include <string.h>
char *strtok(char *str, const char *delim);strtok 函数会: 记住位置:在第一次调用后,它内部保存了当前处理的位置 继续分割:后续调用时从上次结束的位置继续
#include <stdio.h>
#include <string.h>
int main() {
char str[] = "apple,banana,cherry,date";
char *token;
printf("分割字符串: %s\n", str);
// 第一次调用
token = strtok(str, ",");
// 后续调用
while (token != NULL) {
printf("Token: %s\n", token);
token = strtok(NULL, ","); //告诉函数"继续处理同一个字符串,从上一次的位置开始"
}
return 0;
}
#include <string.h>
char *strerror(int errnum);errnum:错误代码(通常是errno变量的值)
#include <stdio.h>
#include <string.h>
#include <errno.h>
int main() {
// 假设发生了文件不存在的错误
errno = 2; // ENOENT 错误代码
printf("错误说明: %s\n", strerror(errno));
// 输出: No such file or directory
return 0;
}在不同的系统和C语⾔标准库的实现中都规定了⼀些错误码,⼀般是放在
errno.h这个头文件中说 明的,C语言程序启动的时候就会使用一个全局的变量errno来记录程序的当前错误码,只不过程 序启动的时候errno是 0,表示没有错误,当我们在使用标准库中的函数的时候发生了某种错误, 就会将对应的错误码,存放在errno中,而一个错误码的数字是整数,很难理解是什么意思,所 以每一个错误码都是有对应的错误信息的。strerror函数就可以将错误码对应的错误信息字符串的地 址返回。
我们看看0-10对应的错误码表示什么
#include <errno.h>
#include <string.h>
#include <stdio.h>
//我们打印—下0~10这些错误码对应的信息
int main()
{
int i = 0;
for (i = 0; i <= 10; i++) {
printf("%d: %s\n", i, strerror(i));
}
return 0;
}0: No error
1: Operation not permitted
2: No such file or directory
3: No such process
4: Interrupted function call
5: Input/output error
6: No such device or address
7: Arg list too long
8: Exec format error
9: Bad file descriptor
10: No child processes下面我们简单讲解一下
FILE这个结构体的内容
我们看下面这段代码
/*
* 错误处理演示程序
* 展示strerror和errno的使用方法
*/
// 包含标准输入输出头文件,提供FILE类型和fopen、printf等函数
#include <stdio.h>
// 包含字符串处理头文件,提供strerror函数
#include <string.h>
// 包含错误号定义头文件,提供errno变量和错误代码常量
#include <errno.h>
// 包含文件控制头文件,提供文件操作相关函数和常量(在此程序中未实际使用)
#include <fcntl.h>
// 主函数,程序入口点
int main() {
// 声明文件指针变量,用于指向打开的文件
// FILE是一个结构体类型,包含文件操作所需的所有信息
FILE *file;
// 尝试以只读模式("r")打开一个不存在的文件
// fopen函数返回:
// - 成功:指向FILE结构的指针
// - 失败:NULL指针,同时设置errno变量
file = fopen("nonexistent_file.txt", "r");
// 检查文件是否打开成功
// 由于文件不存在,fopen会返回NULL
if (file == NULL) {
// 输出错误代码:errno是一个全局变量,存储最近一次系统调用的错误代码
// 此时errno的值应该是2(ENOENT),表示"No such file or directory"
printf("错误代码: %d\n", errno);
// 使用strerror函数将错误代码转换为可读的错误描述字符串
// strerror(errno)会返回类似于"No such file or directory"的字符串
printf("错误描述: %s\n", strerror(errno));
}
// 注意:如果文件打开成功,这里应该有关闭文件的代码
// else {
// fclose(file);
// }
// 演示循环:展示前5个错误代码对应的描述信息
// 注意:不是所有数字都有对应的错误描述,有些可能是"Unknown error"
for (int i = 0; i < 5; i++) {
// 对每个错误代码i,输出其对应的错误描述
// strerror(i)会查找代码i对应的错误描述字符串
printf("错误代码 %d: %s\n", i, strerror(i));
}
// 程序正常结束,返回0表示成功
return 0;
}
FILE *file; 声明一个文件指针,此时它还没有指向任何有效的文件结构。fopen("nonexistent_file.txt", "r") 尝试打开文件,但由于文件不存在而失败。errno 被自动设置为相应的错误代码(通常是2,表示文件不存在)
strerror(errno) 将数字错误代码转换为人类可读的描述
C 标准库中提供了许多函数来操作 FILE 结构体,从文件的打开、读取、写入到关闭文件等。以下是与 FILE 类型相关的常见函数及其功能解释。
打开一个文件并返回一个文件指针
(FILE*)
FILE *fopen(const char *filename, const char *mode);filename:文件的路径。mode:文件打开模式(如 “r”, “w”, “a”, “rb”, “wb” 等)。FILE*指针;如果失败,返回 NULL。FILE *file = fopen("example.txt", "r");
if (file == NULL) {
perror("Error opening file");
}关闭一个打开的文件。
int fclose(FILE *stream);stream:指向一个已打开文件的 FILE*。
0,失败返回 EOF。
fclose(file);从文件中读取数据到内存。
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);ptr:指向存储读取数据的内存块。
size:每个数据项的字节大小。
stream:文件指针。
char buffer[100];
size_t n = fread(buffer, 1, sizeof(buffer), file);向文件中写入数据。
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);ptr:指向要写入的数据的内存块。
size:每个数据项的字节大小。
count:要写入的数据项数量。
stream:文件指针。
const char *data = "Hello, World!";
fwrite(data, 1, strlen(data), file);从文件中读取一个字符。
int fgetc(FILE *stream);stream:文件指针。
int c = fgetc(file);
if (c == EOF) {
printf("End of file or error.\n");
}向文件写入一个字符。
int fputc(int c, FILE *stream);c:要写入的字符。
stream:文件指针。
fputc('A', file);从文件中读取一行(包含换行符)。
char *fgets(char *str, int n, FILE *stream);str:存储读取行的缓冲区。n:最多读取的字符数(包括 \0 字符)。stream:文件指针。char line[100];
if (fgets(line, sizeof(line), file)) {
printf("Line: %s", line);
}向文件写入一个字符串。
int fputs(const char *str, FILE *stream);str:要写入的字符串。
stream:文件指针。
fputs("Hello, World!", file);刷新文件流缓冲区,即将缓冲区中的数据写入文件。
int fflush(FILE *stream);stream:文件指针。如果为 NULL,则刷新所有输出流。
fflush(file);移动文件指针到指定位置。
int fseek(FILE *stream, long offset, int whence);stream:文件指针。
offset:偏移量。
whence:起始位置(SEEK_SET, SEEK_CUR, SEEK_END)。
fseek(file, 0, SEEK_END); // 移动到文件末尾获取当前文件指针的位置。
long ftell(FILE *stream);stream:文件指针。
long pos = ftell(file);将文件指针移动到文件开头,并清除文件的错误标志。
void rewind(FILE *stream);stream:文件指针。rewind(file); // 将文件指针移回文件开头检查是否到达文件末尾。
int feof(FILE *stream);stream:文件指针。
if (feof(file)) {
printf("End of file reached.\n");
}检查文件是否发生错误。
int ferror(FILE *stream);stream:文件指针。
0。
if (ferror(file)) {
printf("Error reading from file.\n");
}打印文件操作相关的错误信息。
void perror(const char *str);str:一个自定义的前缀字符串(如错误发生的上下文)。perror("File opening error");perror 函数将当前错误代码对应的描述信息输出到标准错误流(stderr),并可以附加自定义的前缀信息。
#include <stdio.h>
void perror(const char *s);s:自定义的前缀字符串(可以为NULL)
#include <stdio.h>
#include <errno.h>
int main() {
FILE *file;
// 尝试打开不存在的文件
file = fopen("nonexistent_file.txt", "r");
if (file == NULL) {
// 使用 perror 输出错误信息
perror("文件打开失败");
// 输出: 文件打开失败: No such file or directory
}
return 0;
}字符函数和字符串函数是 C 语言中处理字符和字符串的重要工具,它们用于执行一系列与字符和字符串相关的操作,广泛应用于数据处理、文本处理和文件处理等多个领域。