C语言基础练习:13个核心字符串与数据处理函数封装实战

Nora
Nora
发布时间:2026-10-16| 5人浏览过
原创

本文详细整理了C语言中常见的字符串处理与数据转换函数封装案例,包括闰年判断、字符串查找替换、类型互转及GPS数据解析等13个经典实例,帮助读者掌握指针操作与底层算法逻辑。

封装函数:判断闰年与平年

该函数通过返回值区分传入年份的属性。逻辑上,若年份能被4整除且不能被100整除,或者能被400整除,则为闰年。本例约定返回0表示闰年,返回1表示平年。

#include <stdio.h>
// 函数声明
int GetYearSate(int year);

int main()
{
    int year;
    printf("请输入年份:");
    scanf("%d",&year);
    // 根据返回值判断结果
    if(GetYearSate(year))
    {
        printf("平年.\n");
    }
    else
    {
        printf("闰年.\n");
    }
    return 0;
}

/*
函数功能: 判断平年闰年
返回值: 0表示闰年 1表示平年
*/
int GetYearSate(int year)
{
    if((year%4==0 && year%100!=0)||(year%400==0))
    {
        return 0;
    }
    return 1;
}

封装函数:字符串查找(参考strstr)

自定义 `my_strstr` 函数用于在源字符串中查找目标子串的首地址。操作时需引入 <string.h> 以使用 strlen,并建议通过 man strstr 查阅标准库手册了解接口规范。

#include <stdio.h>
#include <string.h> // 需包含此头文件
char *my_strstr(char *src_str,char *find_str);

int main()
{
    char src_str[100];
    char find_str[100];
    printf("请输入源字符串:");
    scanf("%s",src_str);
    printf("请输入查找的字符串:");
    scanf("%s",find_str);
    
    // 对比系统函数与自定义函数的输出
    printf("系统strstr结果:%s\n",strstr(src_str,find_str));
    printf("自定义my_strstr结果:%s\n",my_strstr(src_str,find_str));
    return 0;
}

// 函数功能: 字符串查找
// 返回值: 找到返回首地址,未找到返回NULL
char *my_strstr(char *src_str,char *find_str)
{
    int src_len;
    int find_len;
    int i,j;
    
    src_len=strlen(src_str);
    find_len=strlen(find_str);
    
    for(i=0;i<src_len;i++)
    {
        for(j=0;j<find_len;j++)
        {
            if(src_str[i+j]!=find_str[j])break;
        }
        // 若内层循环完整执行,说明匹配成功
        if(j==find_len)
        {
            return src_str+i;
        }
    }
    return NULL;
}

封装函数:字符串比较(参考strcmp)

手动实现字符串比对逻辑,逐个字符比较ASCII值。当两字符串完全一致时返回0,否则返回1。注意原代码逻辑仅判断相等性,实际应用中可返回差值。

#include <stdio.h>
#include <string.h>
int my_strcmp(char *s1,char *s2);

int main()
{
    char str1[100];
    char str2[100];
    printf("请输入字符串1:");
    scanf("%s",str1);
    printf("请输入字符串2:");
    scanf("%s",str2);
    
    printf("系统strcmp结果:%d\n",strcmp(str1,str2));
    printf("自定义my_strcmp结果:%d\n",my_strcmp(str1,str2));
    return 0;
}

/*
函数功能: 比较两个字符串是否相等
返回值: 0表示相等 1表示不相等
*/
int my_strcmp(char *s1,char *s2)
{
    while(*s1!='\0' && *s2!='\0')
    {
        if(*s1!=*s2)break;
        s1++;
        s2++;
    }
    if(*s1=='\0'&&*s2=='\0')return 0;
    return 1;
}

封装函数:字符串拼接(参考strcat)

通过移动指针至源字符串末尾,然后将目标字符串内容逐字节拷贝。需注意缓冲区溢出风险,实际应用应确保目标数组空间充足。

#include <stdio.h>
#include <string.h>
char *my_strcat(char *s1,char *s2);

int main()
{
    char str1[100];
    char str2[100];
    printf("请输入字符串1:");
    scanf("%s",str1);
    printf("请输入字符串2:");
    scanf("%s",str2);
    
    printf("拼接的结果:%s\n",my_strcat(str1,str2));
    return 0;
}

char *my_strcat(char *s1,char *s2)
{
    char *p=s1; // 记录源字符串的首地址以便返回
    while(*s1 != '\0'){s1++;} // 指针偏移到结尾
    while(*s2!='\0')
    {
        *s1=*s2;
        s2++;
        s1++;
    }
    *s1='\0'; // 添加结束符
    return p;
}

封装函数:字符串转整数(参考atoi)

遍历字符串,识别数字字符后通过乘10累加的方式构建整数。遇到非数字字符即停止转换。未处理符号位与溢出异常,适用于基础教学场景。

#include <stdio.h>
#include <string.h>
int my_atoi(char *str);

int main()
{
    char buff[100];
    printf("请输入一个整数字符串:");
    scanf("%s",buff);
    printf("系统atoi转换结果:%d\n",atoi(buff));
    printf("自定义my_atoi转换结果:%d\n",my_atoi(buff));
    return 0;
}

/*
函数功能: 字符串转整数 (支持正整数)
返回值: 转换后的整数,失败返回0
*/
int my_atoi(char *str)
{
    int data=0;
    while(*str!='\0')
    {
        if(*str>='0' && *str<='9')
        {
            data*=10; 
            data+=*str-'0';
        }
        else
        {
            break;
        }
        str++;
    }
    return data;
}

封装函数:字符串转浮点数(参考atof)

分离小数点前后的部分分别处理。整数部分常规累乘,小数部分提取后配合 my_pow 计算幂次进行合成。注意精度限制。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

double my_pow(double x,int y);
double my_atof(char *str,int cnt);

int main()
{
    char buff[100];
    printf("请输入一个浮点数字符串:");
    scanf("%s",buff);
    // cnt为指定保留的小数位数
    printf("自定义my_atof转换结果:%lf\n",my_atof(buff,3));
    return 0;
}

double my_atof(char *str,int cnt)
{
    int data_int=0;
    int data_frac=0;
    double result=0.0;
    int cnt_f=0;
    
    // 1. 处理整数部分
    while(*str!='\0' && *str!='.')
    {
        if(*str>='0' && *str<='9')
        {
            result*=10;
            result+=*str-'0';
        }
        else break;
        str++;
    }
    if(*str == '.') str++; // 跳过 "."
    
    // 2. 处理小数部分
    while(*str!='\0' && cnt_f!=cnt)
    {
        if(*str>='0' && *str<='9')
        {
            data_frac*=10;
            data_frac+=*str-'0';
            cnt_f++;
        }
        else break;
        str++;
    }
    
    // 3. 合成结果
    int actual_cnt = (cnt > cnt_f) ? cnt_f : cnt;
    result += data_frac * my_pow(0.1, actual_cnt);
    return result;
}

double my_pow(double x,int y)
{
    double tmp=1.0;
    int i;
    for(i=0;i<y;i++)
    {
        tmp=tmp*x;
    }
    return tmp;
}

封装函数:整数转字符串

通过取余分离每一位数字存入临时数组,随后逆序拷贝至目标字符串。此方法简单有效,未处理负号情况。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void int_to_str(char *str,int data);
int main()
{
    int data;
    char buff[100];
    printf("请输入一个整数:");
    scanf("%d",&data);
    int_to_str(buff,data);
    printf("转换结果: %s\n",buff);
    return 0;
}

void int_to_str(char *str,int data)
{
    char temp_buf[100];
    int i=0;
    int j=0;
    
    if(data == 0) {
        str[0] = '0';
        str[1] = '\0';
        return;
    }

    while(data)
    {
        temp_buf[i]=data%10+'0';
        data=data/10;
        i++;
    }
    // 逆序放入目标字符串
    for(j=0;j<i;j++)
    {
        str[j]=temp_buf[i-1-j];
    }
    str[j]='\0';
}

封装函数:浮点数转字符串

将浮点数拆分为整数和小数两部分独立转换,中间插入小数点连接。涉及辅助幂函数计算小数权重。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int my_pow_int(int x,int y);
void double_to_str(char *str,double data_f,int cnt);

int main()
{
    double data;
    char buff[100];
    printf("请输入一个浮点数:");
    scanf("%lf",&data);
    double_to_str(buff,data,5);
    printf("转换结果: %s\n",buff);
    return 0;
}

void double_to_str(char *str,double data_f,int cnt)
{
    char temp_buf[50];
    int i=0, n=0, j=0;
    int data_i_part = (int)data_f;
    double temp_f = data_f - data_i_part;
    int data_frac_part = (int)(temp_f * my_pow_int(10,cnt));
    
    // 1. 转换整数部分
    while(data_i_part)
    {
        temp_buf[i]=data_i_part%10+'0';
        data_i_part=data_i_part/10;
        i++;
    }
    for(j=0;j<i;j++)
    {
        str[j]=temp_buf[i-1-j];
    }
    str[j]='.';
    
    // 2. 转换小数部分
    while(data_frac_part)
    {
        temp_buf[n]=data_frac_part%10+'0';
        data_frac_part=data_frac_part/10;
        n++;
    }
    for(j=0;j<n;j++)
    {
        str[j+i+1]=temp_buf[n-1-j];
    }
    str[j+i+1]='\0';
}

int my_pow_int(int x,int y)
{
    int tmp=1;
    for(int i=0;i<y;i++) tmp*=x;
    return tmp;
}

封装函数:判断回文字符串

利用双指针思想,从两端向中间靠拢比较字符。若任意位置字符不匹配则立即跳出,若遍历完成无差异则为回文。

#include <stdio.h>
#include <string.h>
int func_is_palindrome(char *p);

int main()
{
    char buff[100];
    printf("输入字符串:");
    scanf("%s",buff);
    if(func_is_palindrome(buff))printf("是回文.\n");
    else printf("不是回文.\n");
    return 0;
}

int func_is_palindrome(char *p)
{
    int len = strlen(p);
    for(int i=0; i<len/2; i++)
    {
        if(p[i]!=p[len-1-i]) return 0;
    }
    return 1;
}

封装函数:字符串替换

较复杂的逻辑:先定位子串,再根据源串与替换串长度差值,决定向前压缩还是向后扩展内存,最后填充新内容。注意数组边界检查在实际生产中必不可少。

#include <stdio.h>
#include <string.h>
void str_replace(char *str1, char *str2, char *str3);

int main()
{
    char str1[100] = "123A789";
    char str2[100] = "A";
    char str3[100] = "XX";
    str_replace(str1, str2, str3);
    printf("替换结果: %s\n", str1);
    return 0;
}

void str_replace(char *str1, char *str2, char *str3)
{
    int len1 = strlen(str1);
    int len2 = strlen(str2);
    int len3 = strlen(str3);
    
    for(int i=0; i<len1; i++)
    {
        // 查找匹配
        bool match = true;
        for(int j=0; j<len2; j++)
        {
            if(str1[i+j] != str2[j]) { match=false; break; }
        }
        if(!match || i+len2 > len1) continue;
        
        // 处理长度差异导致的移位
        if(len2 > len3)
        {
            int diff = len2 - len3;
            for(int k=i+len2; k<len1; k++)
                str1[k-diff] = str1[k];
            str1[len1-diff]='\0';
            len1 -= diff;
        }
        else if(len2 < len3)
        {
            int diff = len3 - len2;
            for(int k=len1; k>=i+len2; k--)
                str1[k+diff] = str1[k];
            str1[len1+diff]='\0';
            len1 += diff;
        }
        // 写入新内容
        for(int j=0; j<len3; j++)
            str1[i+j] = str3[j];
        
        // 修正当前索引继续搜索
        i += len3 - 1;
    }
}

封装函数:清除二维数组的指定行

演示如何通过指向数组的指针访问二维矩阵,并将指定行的所有元素重置为特定值。

#include <stdio.h>
void clear_row(int (*p)[5], int val, int row_idx);

int main()
{
    int buff[][5]=
    {{1,2,3,4,5},
     {11,12,13,14,15},
     {21,22,23,24,25}};
     
    printf("源数据:\n");
    for(int i=0; i<3; i++)
        for(int j=0; j<5; j++)
            printf("%d ", buff[i][j]);
        printf("\n");
    
    clear_row(buff, 888, 1); // 清除第2行(索引1)
    
    printf("清除之后:\n");
    for(int i=0; i<3; i++)
        for(int j=0; j<5; j++)
            printf("%d ", buff[i][j]);
    printf("\n");
    return 0;
}

void clear_row(int (*p)[5], int val, int row_idx)
{
    for(int i=0; i<5; i++)
        p[row_idx][i] = val;
}

封装函数:字符串大小写互换

通过 ASCII 码偏移量(大写与小写相差32)实现转换。传入标志位 `flag` 区分方向:0为大转小,1为小转大。

#include <stdio.h>
#include <string.h>
void swap_case(char *str, int flag);

int main()
{
    char buff[100];
    printf("输入字符串:");
    scanf("%s",buff);
    swap_case(buff, 0); // 大写转小写
    printf("Result1: %s\n", buff);
    swap_case(buff, 1); // 小写转大写
    printf("Result2: %s\n", buff);
    return 0;
}

void swap_case(char *str, int flag)
{
    while(*str!='\0')
    {
        if(flag)
        {
            if(*str>='a' && *str<='z')
                *str = *str - 32; // 小 -> 大
        }
        else
        {
            if(*str>='A' && *str<='Z')
                *str = *str + 32; // 大 -> 小
        }
        str++;
    }
}

封装函数:GPS NMEA数据解析

针对 GPS 模块输出的 NMEA 协议字符串,通过查找特定指令头(如 $GNGGA),按逗号计数定位字段位置,提取经纬度或时间数据。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int GPS_GetData(const char *gps_src, const char *find_head, char *buff, int field_idx);

int main()
{
    const char gps_buff[] = "$GNGGA,114955.000,2842.4158,N,11549.5439,E,1,05,3.8,54.8,M,0.0,M,,*4F";
    char buff[100];
    
    // 提取纬度 (通常在$GNGGA的第2域,具体依协议而定)
    GPS_GetData(gps_buff, "$GNGGA", buff, 2);
    printf("纬度字段: %s\n", buff);
    
    return 0;
}

/*
函数功能: 提取NMEA字符串中指定域的字段
参数: gps_src源串, find_head指令头, buff接收缓冲, field_idx目标逗号序号
返回值: 提取到的字符数
*/
int GPS_GetData(const char *gps_src, const char *find_head, char *buff, int field_idx)
{
    const char *p = strstr(gps_src, find_head);
    if(p == NULL) return 0;
    
    p += strlen(find_head);
    
    int commas = 0;
    while(*p != '\0' && commas < field_idx)
    {
        if(*p == ',') commas++;
        if(commas == field_idx) break;
        p++;
    }
    
    if(commas < field_idx) return 0;
    p++; // 跳过当前逗号
    
    int count = 0;
    while(*p != '\0' && *p != ',')
    {
        buff[count++] = *p;
        p++;
    }
    buff[count] = '\0';
    return count;
}

封装函数:十进制转十六进制字符串

利用除基取余法,将余数映射到 0-F 字符表,最后逆序输出。

#include <stdio.h>

int main()
{
    int number = 255;
    char hex_chars[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    char result[100];
    int i=0;
    
    do {
        result[i++] = hex_chars[number % 16];
        number /= 16;
    } while(number > 0);
    
    printf("0x");
    for(int j=i-1; j>=0; j--)
        printf("%c", result[j]);
    printf("\n");
    return 0;
}
以上就是C语言字符串处理与基础算法封装的详细内容,更多关于C语言指针与内存管理技巧的资料请关注本站其它相关文章!
相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。