20260103_192900 字符串相关函数与方法

1. strlen(str)

方法用法说明

  • 功能:计算C风格字符串的有效字符长度(不包含字符串末尾的结束符\0)。
  • 参数:str:待计算长度的字符数组(C风格字符串)。
  • 返回值:非负整数,代表字符串的有效字符个数。
  • 注意:仅识别\0前的字符,若字符数组未以\0结尾,会出现未定义行为。
例题1
需求

接收用户输入的一个字符串,判断其长度是否在6-16位之间(符合常见密码长度要求),并输出对应结果。

#include <cstring>
#include <iostream>
using namespace std;

int main() {
    char input[50]; // 预留足够大的内存存储用户输入
    cout << "请输入一个字符串(尝试作为密码):";
    cin >> input;
    
    int len = strlen(input);
    if (len >= 6 && len <= 16) {
        cout << "密码长度符合要求!" << endl;
    } else if (len < 6) {
        cout << "密码过短,长度不足6位!" << endl;
    } else {
        cout << "密码过长,长度超过16位!" << endl;
    }
    return 0;
}
解析
  1. 先定义足够大的字符数组input,避免用户输入内容溢出;
  2. 调用strlen(input)获取用户输入字符串的有效长度,赋值给len(无需指针,直接接收返回值即可);
  3. 通过多分支判断len的范围,输出对应结果,核心是利用strlen的返回值进行长度校验,全程未操作指针。
例题2
需求

定义两个固定字符串,比较它们的长度,输出“哪个字符串更长”或“两个字符串长度相等”。

#include <cstring>
#include <iostream>
using namespace std;

int main() {
    char str1[] = "I love C++";
    char str2[] = "Programming is fun";
    
    int len1 = strlen(str1);
    int len2 = strlen(str2);
    
    if (len1 > len2) {
        cout << "字符串1(" << str1 << ")更长,长度为:" << len1 << endl;
    } else if (len1 < len2) {
        cout << "字符串2(" << str2 << ")更长,长度为:" << len2 << endl;
    } else {
        cout << "两个字符串长度相等,均为:" << len1 << endl;
    }
    return 0;
}
解析
  1. 定义两个以\0结尾的字符数组str1str2(编译器自动为字符串常量添加\0);
  2. 分别调用strlen获取两个字符串的长度,存储在len1len2中(无指针操作,仅接收返回值);
  3. 直接比较len1len2的大小,输出对应结论,核心是利用strlen获取固定字符串的长度并进行数值比较。

2. strcmp(s1, s2)

方法用法说明

  • 功能:按**ASCII码值(字典序)**逐字符比较两个C风格字符串,直到出现不同字符或遇到\0
  • 参数:s1s2:待比较的两个字符数组(C风格字符串)。
  • 返回值:
    1. 返回0:s1s2的内容完全相同;
    2. 返回负数:s1的字典序小于s2(首次不同字符中,s1的字符ASCII码更小);
    3. 返回正数:s1的字典序大于s2(首次不同字符中,s1的字符ASCII码更大)。
  • 注意:区分大小写(大写字母ASCII码小于小写字母,如’A’ < ‘a’)。
例题1
需求

接收用户输入的两个字符串,判断它们是否完全相同,输出“相同”或“不同”,并提示字典序大小关系。

#include <cstring>
#include <iostream>
using namespace std;

int main() {
    char s1[50], s2[50];
    cout << "请输入第一个字符串:";
    cin >> s1;
    cout << "请输入第二个字符串:";
    cin >> s2;
    
    int cmp_result = strcmp(s1, s2);
    if (cmp_result == 0) {
        cout << "两个字符串完全相同!" << endl;
    } else if (cmp_result < 0) {
        cout << "两个字符串不同," << s1 << " 字典序小于 " << s2 << endl;
    } else {
        cout << "两个字符串不同," << s1 << " 字典序大于 " << s2 << endl;
    }
    return 0;
}
解析
  1. 定义两个字符数组s1s2存储用户输入,预留足够内存;
  2. 调用strcmp(s1, s2)进行字符串比较,将返回值存入cmp_result(无指针操作,直接接收比较结果);
  3. 根据cmp_result的三种取值,输出对应结论,核心是利用strcmp的返回值判断字符串是否相同及字典序关系,无需操作指针。
例题2
需求

定义一个“目标字符串”(如"admin"),接收用户输入的字符串作为“输入账号”,判断输入账号是否与目标字符串匹配,实现简单的账号验证功能。

#include <cstring>
#include <iostream>
using namespace std;

int main() {
    char target_account[] = "admin";
    char input_account[50];
    
    cout << "请输入登录账号:";
    cin >> input_account;
    
    if (strcmp(input_account, target_account) == 0) {
        cout << "账号验证通过!" << endl;
    } else {
        cout << "账号错误,请重新输入!" << endl;
    }
    return 0;
}
解析
  1. 定义目标账号target_account和输入账号input_account(字符数组);
  2. 调用strcmp比较两个账号字符串,直接判断返回值是否为0(0代表完全匹配);
  3. 输出验证结果,核心是利用strcmp的返回值0判断字符串完全匹配,全程仅操作字符数组和返回值,无指针参与。

3. strncmp(s1, s2, n)

方法用法说明

  • 功能:按ASCII码值(字典序)比较两个C风格字符串的前n个字符,超出字符串长度或遇到\0则停止比较。
  • 参数:
    1. s1s2:待比较的两个字符数组(C风格字符串);
    2. n:需要比较的前n个字符个数(非负整数)。
  • 返回值:与strcmp一致(0代表前n个字符相同,负数代表s1前n个字符字典序更小,正数反之)。
  • 注意:仅比较前n个字符,即使后续字符不同,也不影响结果,安全性高于strcmp(可限制比较长度)。
例题1
需求

判断两个文件名的“前缀(前3个字符)”是否相同(如"file1.txt"和"file2.jpg"),输出“前缀相同”或“前缀不同”。

#include <cstring>
#include <iostream>
using namespace std;

int main() {
    char file1[] = "file1.txt";
    char file2[] = "file2.jpg";
    const int prefix_len = 3; // 定义前缀长度为3
    
    int cmp_result = strncmp(file1, file2, prefix_len);
    if (cmp_result == 0) {
        cout << "两个文件的前" << prefix_len << "个字符前缀相同!" << endl;
    } else {
        cout << "两个文件的前" << prefix_len << "个字符前缀不同!" << endl;
    }
    return 0;
}
解析
  1. 定义两个文件名字符数组file1file2,指定前缀长度prefix_len为3;
  2. 调用strncmp(file1, file2, prefix_len),仅比较前3个字符,接收返回值cmp_result(无指针操作);
  3. 根据返回值是否为0,判断前缀是否相同,核心是利用strncmp的长度限制功能,仅比较指定前n个字符,无需操作指针。
例题2
需求

接收用户输入的“验证码”,已知正确验证码为"AB1234",只需验证用户输入的前4位是否正确,实现简化版验证码验证。

#include <cstring>
#include <iostream>
using namespace std;

int main() {
    char correct_code[] = "AB1234";
    char input_code[50];
    const int verify_len = 4; // 只需验证前4位
    
    cout << "请输入验证码(前4位为AB12):";
    cin >> input_code;
    
    if (strncmp(input_code, correct_code, verify_len) == 0) {
        cout << "验证码前4位验证通过!" << endl;
    } else {
        cout << "验证码前4位错误,请重新输入!" << endl;
    }
    return 0;
}
解析
  1. 定义正确验证码和用户输入验证码的字符数组,指定验证长度verify_len为4;
  2. 调用strncmp仅比较前4个字符,避免用户输入完整验证码带来的安全风险;
  3. 判断返回值是否为0,输出验证结果,核心是利用strncmp的长度限制功能,无需操作指针,仅关注前n个字符的匹配情况。

4. strcat(s1, s2)

方法用法说明

  • 功能:将字符串s2的全部内容(包含末尾的\0追加拼接到字符串s1的末尾,覆盖s1原来的\0
  • 参数:
    1. s1:目标字符数组(接收拼接后的内容);
    2. s2:源字符数组(待拼接的内容)。
  • 返回值:指向s1的指针(可忽略,直接使用s1即可)。
  • 注意:必须保证s1的内存空间足够大,能够容纳s1原有内容+s2的全部内容,否则会出现缓冲区溢出。
例题1
需求

接收用户输入的“姓氏”和“名字”,拼接成完整姓名并输出(如姓氏“张”,名字“三”,拼接为“张三”)。

#include <cstring>
#include <iostream>
using namespace std;

int main() {
    char full_name[50]; // 预留足够大的空间存储完整姓名
    char last_name[20], first_name[20];
    
    cout << "请输入你的姓氏:";
    cin >> last_name;
    cout << "请输入你的名字:";
    cin >> first_name;
    
    // 先将姓氏拷贝到full_name(避免full_name初始值干扰)
    strcpy(full_name, last_name);
    // 拼接名字到full_name末尾
    strcat(full_name, first_name);
    
    cout << "你的完整姓名是:" << full_name << endl;
    return 0;
}
解析
  1. 定义足够大的full_name存储拼接结果,避免缓冲区溢出;
  2. 先通过strcpy将姓氏拷贝到full_name(初始化full_name,避免其默认随机值干扰);
  3. 调用strcat(full_name, first_name),将名字追加到姓氏末尾,直接使用full_name即可获取拼接结果,无需操作返回值(指针),全程仅操作字符数组。
例题2
需求

定义文件基础路径(如"D:/docs/“)和文件名(如"report.txt”),拼接成完整文件路径并输出。

#include <cstring>
#include <iostream>
using namespace std;

int main() {
    char full_path[100] = "D:/docs/"; // 初始化基础路径,预留足够空间
    char filename[] = "report.txt";
    
    // 拼接文件名到基础路径末尾
    strcat(full_path, filename);
    
    cout << "完整文件路径是:" << full_path << endl;
    return 0;
}
解析
  1. 初始化基础路径full_path,并预留足够空间(确保能容纳基础路径+文件名);
  2. 调用strcat将文件名追加到基础路径末尾,full_path原来的\0会被文件名覆盖,文件名末尾的\0会被保留;
  3. 直接输出full_path即可得到完整路径,无需操作strcat的返回值(指针),核心是利用strcat的拼接功能,仅操作字符数组。

5. strncat(s1, s2, n)

方法用法说明

  • 功能:将字符串s2前n个字符追加拼接至字符串s1的末尾,拼接完成后自动添加\0
  • 参数:
    1. s1:目标字符数组(接收拼接后的内容);
    2. s2:源字符数组(待拼接的内容);
    3. n:需要拼接的s2的前n个字符个数。
  • 返回值:指向s1的指针(可忽略,直接使用s1即可)。
  • 注意:
    1. 保证s1的内存空间足够大,容纳s1原有内容+n个字符;
    2. s2的长度小于n,则仅拼接s2的全部内容,后续自动补\0,安全性高于strcat
例题1
需求

定义字符串“CS”和“Engineering”,仅拼接“Engineering”的前2个字符,生成专业缩写并输出(预期结果:CSEn)。

#include <cstring>
#include <iostream>
using namespace std;

int main() {
    char abbr[20] = "CS"; // 初始化缩写前缀
    char major[] = "Engineering";
    const int concat_len = 2; // 仅拼接前2个字符
    
    // 拼接major的前2个字符到abbr末尾
    strncat(abbr, major, concat_len);
    
    cout << "专业缩写为:" << abbr << endl;
    return 0;
}
解析
  1. 初始化缩写前缀abbr,定义待拼接的专业名称和拼接长度concat_len为2;
  2. 调用strncat仅拼接major的前2个字符(“En”),拼接后自动为abbr添加\0
  3. 直接输出abbr得到结果,无需操作返回值(指针),核心是利用strncat的长度限制功能,避免拼接过多字符,无需操作指针。
例题2
需求

定义用户名“zhangsan”和临时密码前缀“temp_”,拼接用户名的前3个字符到前缀后,生成临时密码并输出(预期结果:temp_zha)。

#include <cstring>
#include <iostream>
using namespace std;

int main() {
    char temp_pwd[50] = "temp_"; // 初始化密码前缀
    char username[] = "zhangsan";
    const int concat_len = 3; // 仅拼接前3个字符
    
    // 拼接用户名前3个字符到密码前缀末尾
    strncat(temp_pwd, username, concat_len);
    
    cout << "生成的临时密码是:" << temp_pwd << endl;
    return 0;
}
解析
  1. 初始化临时密码前缀temp_pwd,预留足够空间,定义用户名和拼接长度;
  2. 调用strncat仅拼接用户名的前3个字符,避免泄露完整用户名,拼接后自动补\0
  3. 直接输出temp_pwd得到临时密码,无需操作指针,核心是利用strncat的长度限制功能,安全地拼接指定数量的字符。

6. strcpy(s1, s2)

方法用法说明

  • 功能:将字符串s2的全部内容(包含末尾的\0覆盖拷贝到字符数组s1中,完全替换s1原有的内容。
  • 参数:
    1. s1:目标字符数组(接收拷贝后的内容);
    2. s2:源字符数组(待拷贝的内容)。
  • 返回值:指向s1的指针(可忽略,直接使用s1即可)。
  • 注意:必须保证s1的内存空间足够大,能够容纳s2的全部内容,否则会出现缓冲区溢出。
例题1
需求

接收用户输入的一条消息,将其拷贝到“消息存储变量”中,输出“已保存的消息”。

#include <cstring>
#include <iostream>
using namespace std;

int main() {
    char saved_msg[100]; // 存储拷贝后的消息
    char input_msg[100];
    
    cout << "请输入需要保存的消息:";
    cin >> input_msg;
    
    // 将输入消息拷贝到保存变量中
    strcpy(saved_msg, input_msg);
    
    cout << "消息已保存,保存的内容是:" << saved_msg << endl;
    return 0;
}
解析
  1. 定义输入消息和保存消息的字符数组,预留足够内存;
  2. 调用strcpy(saved_msg, input_msg),将输入消息完整拷贝到保存变量中,覆盖saved_msg原有内容;
  3. 直接输出saved_msg得到保存的消息,无需操作返回值(指针),核心是利用strcpy的完整拷贝功能,仅操作字符数组,无指针参与。
例题2
需求

定义一个字符串数组存储3个文件名,将第二个文件名拷贝到“选中文件”变量中,输出“当前选中的文件”。

#include <cstring>
#include <iostream>
using namespace std;

int main() {
    char files[3][50] = {"a.txt", "b.jpg", "c.doc"}; // 字符串数组存储文件名
    char selected_file[50]; // 存储选中的文件
    
    // 拷贝第二个文件名(下标为1)到选中文件变量
    strcpy(selected_file, files[1]);
    
    cout << "当前选中的文件是:" << selected_file << endl;
    return 0;
}
解析
  1. 定义二维字符数组files存储3个文件名,定义selected_file存储选中的文件;
  2. 调用strcpyfiles[1](第二个文件名)完整拷贝到selected_file中,覆盖其原有内容;
  3. 直接输出selected_file得到结果,无需操作指针,核心是利用strcpy拷贝字符串数组中的指定元素,仅操作字符数组。

7. strncpy(s1, s2, n)

方法用法说明

  • 功能:将字符串s2前n个字符覆盖拷贝到字符数组s1中,替换s1原有的前n个字符。
  • 参数:
    1. s1:目标字符数组(接收拷贝后的内容);
    2. s2:源字符数组(待拷贝的内容);
    3. n:需要拷贝的s2的前n个字符个数。
  • 返回值:指向s1的指针(可忽略,直接使用s1即可)。
  • 注意:
    1. s2的长度小于n,则拷贝s2全部内容后,为s1剩余位置补\0
    2. s2的长度大于等于n,则仅拷贝前n个字符,不会自动为s1添加\0,需手动补充,避免乱码。
例题1
需求

定义一篇短文“C++是一门高效、强大的编程语言”,截取前5个字符作为文章摘要,输出摘要内容。

#include <cstring>
#include <iostream>
using namespace std;

int main() {
    char article[] = "C++是一门高效、强大的编程语言";
    char summary[20]; // 存储摘要
    const int copy_len = 5; // 截取前5个字符
    
    // 拷贝前5个字符到摘要
    strncpy(summary, article, copy_len);
    // 手动补充\0,避免乱码(因为strncpy不会自动补\0)
    summary[copy_len] = '\0';
    
    cout << "文章摘要:" << summary << endl;
    return 0;
}
解析
  1. 定义短文和摘要的字符数组,指定拷贝长度copy_len为5;
  2. 调用strncpy仅拷贝前5个字符到summary,由于s2(article)长度大于5,strncpy不会自动补\0,因此手动为summary[5]赋值\0,避免输出乱码;
  3. 输出摘要内容,无需操作指针,核心是利用strncpy的长度限制功能截取字符串,手动补充\0保证字符串有效性。
例题2
需求

定义一个手机号“13812345678”,截取前3位作为手机号前缀,判断是否为移动前缀(138),输出对应结果。

#include <cstring>
#include <iostream>
using namespace std;

int main() {
    char phone[] = "13812345678";
    char prefix[4]; // 存储3位前缀+1位\0
    const int copy_len = 3; // 截取前3位
    
    // 拷贝前3位字符到前缀
    strncpy(prefix, phone, copy_len);
    // 手动补充\0,确保是合法C风格字符串
    prefix[copy_len] = '\0';
    
    if (strcmp(prefix, "138") == 0) {
        cout << "该手机号是移动手机号(前缀138)" << endl;
    } else {
        cout << "该手机号不是移动手机号(前缀非138)" << endl;
    }
    return 0;
}
解析
  1. 定义手机号和前缀字符数组(前缀数组长度为4,预留\0的位置),指定拷贝长度为3;
  2. 调用strncpy拷贝前3位前缀,手动补充\0,确保prefix是合法的C风格字符串,才能被strcmp正确比较;
  3. strcmp判断前缀是否为138,输出结果,全程无指针操作,核心是利用strncpy截取指定长度的字符,手动补\0保证后续函数正常使用。
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐