首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >收集飞花令碎片——C语言字符函数与字符串函数

收集飞花令碎片——C语言字符函数与字符串函数

作者头像
枫亭湖区
发布2025-11-12 18:08:16
发布2025-11-12 18:08:16
140
举报

一)字符函数

字符函数大部分都定义在<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

代码语言:javascript
复制
#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;
}

字符转换函数(to表示转变的意思)

字符大小写转换函数

我们只需要学习前两种大小写转换函数,后面的我们作了解即可

C语言提供了2个字符转换函数:

代码语言:javascript
复制
int tolower ( int c ); //将参数传进去的⼤写字⺟转⼩写
int toupper ( int c ); //将参数传进去的⼩写字⺟转⼤写
示例代码
代码语言:javascript
复制
#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;
}
代码语言:javascript
复制
#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’==来转换 下面我们介绍几种字符转换函数

atoi() - 字符串转整数
代码语言:javascript
复制
#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() – 字符串转长整数
itoa() - 整数转字符串
代码语言:javascript
复制
#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;
}

sprintf() - 格式化输出到字符串
代码语言:javascript
复制
#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;
}

二)字符串函数

使用前记得添加头文件

代码语言:javascript
复制
#include <string.h>  // 字符串函数
#include <stdio.h>   // 输入输出

字符串长度 - strlen
代码语言:javascript
复制
char str[] = "hello";
int len = strlen(str); // len = 5

字符串复制 - strcpy / strncpy
  • 功能: 将源字符串 src(包括终止空字符 \0)复制到目标缓冲区 dest。
代码语言:javascript
复制
#include <string.h>
char *strcpy(char *dest, const char *src);
  • 代码示例
代码语言:javascript
复制
char src[] = "hello";
char dest[10];
strcpy(dest, src); // dest = "hello"

strncpy

在VS中好像会出现安全性问题,这时候我们可以添加宏定义

代码语言:javascript
复制
#define _CRT_SECURE_NO_WARNINGS

  • 功能: 最多复制 n 个字符从 src 到 dest
代码语言:javascript
复制
#include <string.h>
char *strncpy(char *dest, const char *src, size_t n);
  • 代码示例
代码语言:javascript
复制
#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;
}

字符串连接 - strcat

  • 函数原型
代码语言:javascript
复制
char * strcat ( char * destination, const char * source );
  • 功能: 字符串追加,把source指向的源字符串中的所有字符都追加到destination指向的空间 中。
  • 参数: destination :指针,指向⽬的地空间 source :指针,指向源头数据
  • 返回值: strcat 函数返回的⽬标空间的起始地址
代码语言:javascript
复制
char str[20] = "Hello";
strcat(str, " World");     // "Hello World"
strncat(str, "!!!", 2);    // "Hello World!!"

字符串比较 - strcmp / strncmp
  • 函数原型
代码语言:javascript
复制
int strcmp ( const char * str1, const char * str2 );

  • 功能: ⽤来⽐较str1str2指向的字符串,从两个字符串的第⼀个字符开始⽐较,如果两个字符 的ASCII码值相等,就⽐较下⼀个字符。直到遇到不相等的两个字符,或者字符串结束。 参数: str1 :指针,指向要⽐较的第⼀个字符串 str2 :指针,指向要⽐较的第⼆个字符串
  • 返回值:
  • 标准规定:第⼀个字符串⼤于第⼆个字符串,则返回⼤于0的数字 ◦ 第⼀个字符串等于第⼆个字符串,则返回0 ◦ 第⼀个字符串⼩于第⼆个字符串,则返回⼩于0的数字
  • 代码示例
代码语言:javascript
复制
#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;
}

strncpy
代码语言:javascript
复制
#include <string.h>
int strncmp(const char *str1, const char *str2, size_t n);
  • 功能 比较两个字符串的前 n 个字符
  • 代码示例
代码语言:javascript
复制
#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;
}

字符串查找 - strstr
  • 函数原型
代码语言:javascript
复制
char * strstr ( const char * str1, const char * str2);

strstr 的使⽤得包含<string.h>

  • 参数: str1 :指针,指向了被查找的字符串 str2 :指针,指向了要查找的字符串
  • 返回值: 如果str1指向的字符串中存在str2指向的字符串,那么返回第⼀次出现位置的指针 如果str1指向的字符串中不存在str2指向的字符串,那么返回NULL

  • 代码示例
代码语言:javascript
复制
#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;
}

字符串分隔strtok
  • 函数原型
代码语言:javascript
复制
#include <string.h>
char *strtok(char *str, const char *delim);
  • 参数说明 str:要分割的字符串(第一次调用时传入,后续传入NULL) delim:分隔符字符串(包含所有分隔字符)
  • 返回值 成功:返回指向下一个token的指针 结束:返回NULL(没有更多token)

strtok 函数会: 记住位置:在第一次调用后,它内部保存了当前处理的位置 继续分割:后续调用时从上次结束的位置继续


  • 代码示例
代码语言:javascript
复制
#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;
}
在这里插入图片描述
在这里插入图片描述

错误码 - strerror
  • 函数原型
代码语言:javascript
复制
#include <string.h>
char *strerror(int errnum);
  • 功能 将错误代码转换为对应的错误描述字符串
  • 参数 errnum:错误代码(通常是errno变量的值)
  • 返回值 返回指向错误描述字符串的指针

代码语言:javascript
复制
#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对应的错误码表示什么

代码语言:javascript
复制
#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;
}
代码语言:javascript
复制
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结构体

下面我们简单讲解一下FILE 这个结构体的内容

我们看下面这段代码

代码语言:javascript
复制
/* 
 * 错误处理演示程序
 * 展示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;
}
在这里插入图片描述
在这里插入图片描述
  • 程序执行流程详细说明:
  1. 声明阶段:FILE *file; 声明一个文件指针,此时它还没有指向任何有效的文件结构。
  2. 文件打开尝试:fopen("nonexistent_file.txt", "r") 尝试打开文件,但由于文件不存在而失败。
  3. 错误处理: errno 被自动设置为相应的错误代码(通常是2,表示文件不存在) strerror(errno) 将数字错误代码转换为人类可读的描述
  4. 错误代码演示:循环显示前5个错误代码的描述,帮助理解错误代码与描述之间的映射关系。

在这里插入图片描述
在这里插入图片描述

C 标准库中提供了许多函数来操作 FILE 结构体,从文件的打开、读取、写入到关闭文件等。以下是与 FILE 类型相关的常见函数及其功能解释。


1. fopen()

打开一个文件并返回一个文件指针(FILE*)

代码语言:javascript
复制
FILE *fopen(const char *filename, const char *mode);
  • filename:文件的路径。
  • mode:文件打开模式(如 “r”, “w”, “a”, “rb”, “wb” 等)。
  • 返回值:如果成功,返回一个FILE*指针;如果失败,返回 NULL
代码语言:javascript
复制
FILE *file = fopen("example.txt", "r");
if (file == NULL) {
    perror("Error opening file");
}

2. fclose()

关闭一个打开的文件。

代码语言:javascript
复制
int fclose(FILE *stream);
  • stream:指向一个已打开文件的 FILE*
  • 返回值:成功返回0,失败返回 EOF
代码语言:javascript
复制
fclose(file);

3. fread()

从文件中读取数据到内存。

代码语言:javascript
复制
size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
  • ptr:指向存储读取数据的内存块。
  • size:每个数据项的字节大小。
  • count`:要读取的数据项数量。
  • stream:文件指针。
  • 返回值:成功读取的项数。如果返回值小于 count,可能是到达文件末尾或发生错误。
代码语言:javascript
复制
char buffer[100];
size_t n = fread(buffer, 1, sizeof(buffer), file);

4. fwrite()

向文件中写入数据。

代码语言:javascript
复制
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
  • ptr:指向要写入的数据的内存块。
  • size:每个数据项的字节大小。
  • count:要写入的数据项数量。
  • stream:文件指针。
  • 返回值:成功写入的项数。
代码语言:javascript
复制
const char *data = "Hello, World!";
fwrite(data, 1, strlen(data), file);

5. fgetc()

从文件中读取一个字符。

代码语言:javascript
复制
int fgetc(FILE *stream);
  • stream:文件指针。
  • 返回值:成功时返回一个字符(int 类型,允许返回 EOF)。如果到达文件末尾,返回 EOF。
代码语言:javascript
复制
int c = fgetc(file);
if (c == EOF) {
    printf("End of file or error.\n");
}

6. fputc()

向文件写入一个字符。

代码语言:javascript
复制
int fputc(int c, FILE *stream);
  • c:要写入的字符。
  • stream:文件指针。
  • 返回值:成功时返回写入的字符,失败时返回 EOF。
代码语言:javascript
复制
fputc('A', file);

7. fgets()

从文件中读取一行(包含换行符)。

代码语言:javascript
复制
char *fgets(char *str, int n, FILE *stream);
  • str:存储读取行的缓冲区。
  • n:最多读取的字符数(包括 \0 字符)。
  • stream:文件指针。
  • 返回值:返回指向缓冲区的指针,或者如果读取失败或到达文件末尾返回 NULL。
代码语言:javascript
复制
char line[100];
if (fgets(line, sizeof(line), file)) {
    printf("Line: %s", line);
}

8. fputs()

向文件写入一个字符串。

代码语言:javascript
复制
int fputs(const char *str, FILE *stream);
  • str:要写入的字符串。
  • stream:文件指针。
  • 返回值:成功时返回非负值,失败时返回 EOF。
代码语言:javascript
复制
fputs("Hello, World!", file);

9. fflush()

刷新文件流缓冲区,即将缓冲区中的数据写入文件。

代码语言:javascript
复制
int fflush(FILE *stream);
  • stream:文件指针。如果为 NULL,则刷新所有输出流。
  • 返回值:成功时返回 0,失败时返回 EOF。
代码语言:javascript
复制
fflush(file);

10. fseek()

移动文件指针到指定位置。

代码语言:javascript
复制
int fseek(FILE *stream, long offset, int whence);
  • stream:文件指针。
  • offset:偏移量。
  • whence:起始位置(SEEK_SET, SEEK_CUR, SEEK_END)。
  • 返回值:成功时返回 0,失败时返回 -1。
代码语言:javascript
复制
fseek(file, 0, SEEK_END);  // 移动到文件末尾

11. ftell()

获取当前文件指针的位置。

代码语言:javascript
复制
long ftell(FILE *stream);
  • stream:文件指针。
  • 返回值:返回当前位置的偏移量,失败时返回 -1L。
代码语言:javascript
复制
long pos = ftell(file);

12. rewind()

将文件指针移动到文件开头,并清除文件的错误标志。

代码语言:javascript
复制
void rewind(FILE *stream);
  • stream:文件指针。
代码语言:javascript
复制
rewind(file);  // 将文件指针移回文件开头

13. feof()

检查是否到达文件末尾。

代码语言:javascript
复制
int feof(FILE *stream);
  • stream:文件指针。
  • 返回值:到达文件末尾时返回非零值,否则返回 0。
代码语言:javascript
复制
if (feof(file)) {
    printf("End of file reached.\n");
}

14. ferror()

检查文件是否发生错误。

代码语言:javascript
复制
int ferror(FILE *stream);
  • stream:文件指针。
  • 返回值:如果文件出错,返回非零值,否则返回 0
代码语言:javascript
复制
if (ferror(file)) {
    printf("Error reading from file.\n");
}

15. perror()

打印文件操作相关的错误信息。

代码语言:javascript
复制
void perror(const char *str);
  • str:一个自定义的前缀字符串(如错误发生的上下文)。
代码语言:javascript
复制
perror("File opening error");

额外:perror
  • 功能 perror 函数将当前错误代码对应的描述信息输出到标准错误流(stderr),并可以附加自定义的前缀信息。
  • 函数原型
代码语言:javascript
复制
#include <stdio.h>
void perror(const char *s);
  • 参数 s:自定义的前缀字符串(可以为NULL
  • 基本用法
代码语言:javascript
复制
#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 语言中处理字符和字符串的重要工具,它们用于执行一系列与字符和字符串相关的操作,广泛应用于数据处理、文本处理和文件处理等多个领域。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-11-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一)字符函数
    • 字符分类函数
      • 代码练习
    • 字符转换函数(to表示转变的意思)
      • 字符大小写转换函数
      • 示例代码
      • 字符与数字转换
  • 二)字符串函数
    • 字符串长度 - strlen
    • 字符串复制 - strcpy / strncpy
    • 字符串连接 - strcat
    • 字符串比较 - strcmp / strncmp
    • 字符串查找 - strstr
    • 字符串分隔strtok
    • 错误码 - strerror
    • 额外:perror
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档