c++中string用法详解

news2024/11/7 21:57:17

目录

二、案例需求

三、案例实现

1.首先获取strData中的角色数量

2.创造结构体数组,定义两个索引值

3.循环遍历对结构体User中的Id和Exp进行赋值

4.对结构体数组userArr进行排序

5.展示结果以及最终代码

​四、最后


一、前言

        在C++中,std::string 是一个非常重要的类,用于处理字符串。它是标准模板库(STL)的一部分,并且定义在 <string> 头文件中。

        std::string类中有非常多的api用法,例如返length()返回字符串的长度(字符数),substr() 提取子字符串,replace() 替换子字符串或字符的个数等等。

        但是我不想逐个讲述string类中的api方法,那样没有实际的意义,下面我想通过一个实际的案例来加深你对string用法的印象。

二、案例需求

string strData = "id=TomyClare;exp=9521;id=Sunny;exp=9523;id=DyBaby;exp=25321;id=Simple;exp=25321;id=Bkacs11;exp=2100;";

上面有一段字符串,需求如下:

  1. 依次获取字符串中的数据id(角色名字)和exp(角色武力值),并且放入结构体数组userArr中,结构体定义如下:
    typedef struct User
    {
        string Id;
        int Exp;
    }* pUser;
  2. 将结构体数组中的角色按照exp(角色武力值)进行从大到小排序,如果exp相同则按照id首字母进行排序,并最终打印结构体中角色的数据。

三、案例实现

案例思路:

1.首先获取strData中的角色数量

        根据我们对字符串的观察,strData中的角色数量可以根据字符串中的";"数量除于2得到。

";"对应的ASCII表中的数字59。于是我们可以遍历字符串,并且进行判断得到";"的数量。

代码实现如下:

    // 整个数据
    string strData = "id=TomyClare;exp=9521;id=Sunny;exp=9523;id=DyBaby;exp=25321;id=Simple;exp=25321;id=Bkacs11;exp=2100;";
    // ";"数量
    int count{ 0 };
    for (auto item : strData)
    {
        // 将item字符char类型转换为int类型进行比较,相同count++
        if ((int)item == 59) count++;
    }
    // 角色数量为: 5
    int Usercount{ count / 2 };
    cout << "整个角色数量为:" << Usercount << endl;  
2.创造结构体数组,定义两个索引值
    pUser userArr = new User[Usercount];

    int startIndex{ 0 }, endIndex{ 0 };

        startIndex和endIndex两个索引值变量非常重要,分别代表需要获取id值和exp值的下标,每次会变化。

如下图所示:

3.循环遍历对结构体User中的Id和Exp进行赋值

代码如下:

    for (int i = 0; i < Usercount; i++)
    {
        //"id="中的 i的索引
        startIndex = strData.find("id=",startIndex);
        //";" 的索引
        endIndex = strData.find(";",startIndex + 3);
        // 截取的Id 例如:TomyClare
        userArr[i].Id = strData.substr(startIndex + 3,endIndex - startIndex - 3);

        startIndex = endIndex + 1;

        startIndex = strData.find("exp=", startIndex);

        endIndex = strData.find(";",startIndex + 4);
        // 截取的Exp 例如:9521   stoi() 将string类型转换为int类型
        userArr[i].Exp = stoi(strData.substr(startIndex + 4,endIndex - startIndex - 4));

        // 测试是否赋值成功
        cout << userArr[i].Id << " " << userArr[i].Exp << endl;
        
    }

重点为:startIndex和endIndex两个索引值变量会根据循环不断发生改变,用图片看很好理解。

        在循环赋值操作中分别用到了find() 查找子字符串或字符的位置和substr() 提取子字符串两个std::string方法。

find()函数的详细解释:获取指定字符串的索引值

size_type find(const string& str, size_type pos = 0) const noexcept;

  • str:要查找的子串。
  • pos(可选):开始查找的位置。默认为0,表示从字符串的开头开始查找。

substr()函数的详细解释:用来提取字符串

std::string substr(size_t pos = 0, size_t len = npos) const;

  • pos:起始索引,即子串在字符串中开始的位置(包含在内)。索引从0开始。
  • len:子串的长度(不包含终止索引)。如果省略或提供的值大于从pos到字符串末尾的长度,那么substr()将提取从pos到字符串末尾的所有字符。默认值为std::string::npos,这是一个特殊的常量,表示直到字符串的末尾。

4.对结构体数组userArr进行排序

        排序主要运用了冒泡排序,比较简单,这里就不再进行再多的叙述了,代码如下:

    for (int i = 0; i < Usercount; i++)
    {
        for (int j = 0; j < Usercount - i - 1; j++)
        {
            if (userArr[j].Exp <= userArr[j + 1].Exp)
            {
                User temp = userArr[j];
                userArr[j] = userArr[j + 1];
                userArr[j + 1] = temp;
            }
            // 武力值相同,对角色id进行排序
            else if (userArr[j].Exp == userArr[j + 1].Exp)
            {
                if (userArr[j].Id.compare(userArr[j + 1].Id) == -1)
                {
                    User temp = userArr[j];
                    userArr[j] = userArr[j + 1];
                    userArr[j + 1] = temp;
                }
            }
        }
    }
5.展示结果以及最终代码

代码如下:

#include <iostream>
#include <string>
#include <vector>
using namespace std;

typedef struct User
{
    string Id;
    int Exp;
}* pUser;

int main()
{
    // 整个数据
    string strData = "id=TomyClare;exp=9521;id=Sunny;exp=9523;id=DyBaby;exp=25321;id=Simple;exp=25321;id=Bkacs11;exp=2100;";
    // ";"数量
    int count{ 0 };
    for (auto item : strData)
    {
        // 将item字符char类型转换为int类型进行比较,相同count++
        if ((int)item == 59) count++;
    }
    // 角色数量为: 5
    int Usercount{ count / 2 };
    cout << "整个角色数量为:" << Usercount << endl;  


    pUser userArr = new User[Usercount];
    // 
    int startIndex{ 0 }, endIndex{ 0 };

    for (int i = 0; i < Usercount; i++)
    {
        //"id="中的 i的索引
        startIndex = strData.find("id=",startIndex);
        //";" 的索引
        endIndex = strData.find(";",startIndex + 3);
        // 截取的Id 例如:TomyClare
        userArr[i].Id = strData.substr(startIndex + 3,endIndex - startIndex - 3);

        startIndex = endIndex + 1;

        startIndex = strData.find("exp=", startIndex);

        endIndex = strData.find(";",startIndex + 4);
        // 截取的Exp 例如:9521 
        userArr[i].Exp = stoi(strData.substr(startIndex + 4,endIndex - startIndex - 4));

        // 测试是否赋值成功
        cout << userArr[i].Id << " " << userArr[i].Exp << endl;
        
    }

    for (int i = 0; i < Usercount; i++)
    {
        for (int j = 0; j < Usercount - i - 1; j++)
        {
            if (userArr[j].Exp <= userArr[j + 1].Exp)
            {
                User temp = userArr[j];
                userArr[j] = userArr[j + 1];
                userArr[j + 1] = temp;
            }
            // 武力值相同,对角色id进行排序
            else if (userArr[j].Exp == userArr[j + 1].Exp)
            {
                if (userArr[j].Id.compare(userArr[j + 1].Id) == -1)
                {
                    User temp = userArr[j];
                    userArr[j] = userArr[j + 1];
                    userArr[j + 1] = temp;
                }
            }
        }
    }
    for (int i = 0; i < Usercount; i++)
    {
        cout << endl;
        cout << "排序后的数据";
        cout << userArr[i].Id << " " << userArr[i].Exp << endl;
    }
}

结果图片:

四、最后

        制作不易,熬夜肝的,虽然质量感觉有些欠佳,但还请各位彦祖们点点赞,拯救下秃头的博主吧!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1813666.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

可视化剪辑,账号矩阵管理,视频分发,聚合私信多功能一体化营销工具 源代码开发部署方案

可视化剪辑&#xff0c;账号矩阵管理&#xff0c;视频分发&#xff0c;聚合私信多功能一体化营销工具 源代码开发部署方案 可视化剪辑&#xff1a; 可视化剪辑开发是一种通过图形化界面和拖放操作&#xff0c;以可视化的方式进行影片剪辑和编辑的开发方法。它可以让非专业用户…

什么是校园抄表系统?

1.校园抄表系统的简述 校园抄表系统是当代高校管理中的一个重要组成部分&#xff0c;主要运用于全自动搜集、管理方法与分析校园里的电力能源使用数据&#xff0c;如水电煤等。它通过先进的方式方法&#xff0c;完成了对能源消耗的实时监控系统&#xff0c;提升了电力能源管理…

maven基本操作和配置(idea版基础版)

写在前面&#xff1a;为一位朋友写的一个博客&#xff0c;有需要都可以查看&#xff01; 一、maven是什么&#xff1f; 一句话&#xff1a;管理依赖工具&#xff0c;统一项目结构便于开发&#xff0c;把项目开发和管理的过程抽象成对象模型来管理&#xff08;pom模型&#xf…

@JsonValue和@JsonCreator使用

当实体类中的属性为枚举类型时&#xff0c;将其序列化成json字符串传给前端&#xff0c;传递的应该是有效的值而不是枚举常量。 1. Get-Started Data public class Student {private Long id;private String userName;private String telephone;private String email;private …

C语言 | Leetcode C语言题解之第145题二叉树的后序遍历

题目&#xff1a; 题解&#xff1a; void addPath(int *vec, int *vecSize, struct TreeNode *node) {int count 0;while (node ! NULL) {count;vec[(*vecSize)] node->val;node node->right;}for (int i (*vecSize) - count, j (*vecSize) - 1; i < j; i, --j)…

【C语言】12.C语言内存函数

文章目录 1.memcpy使用和模拟实现2.memmove使用和模拟实现3.memset函数的使用4.memcmp函数的使用 memcpy&#xff1a;内存拷贝 memmove&#xff1a;内存移动 memset&#xff1a;内存设置 memcmp&#xff1a;内存比较 1.memcpy使用和模拟实现 memcpy&#xff1a;内存拷贝 void…

【python】OpenCV—Background Estimation(15)

文章目录 中值滤波中值滤波得到图像背景移动侦测 学习来自 OpenCV基础&#xff08;14&#xff09;OpenCV在视频中的简单背景估计 中值滤波 中值滤波是一种非线性平滑技术&#xff0c;主要用于数字信号处理&#xff0c;特别是在图像处理中去除噪声。 一、定义与原理 定义&am…

如何使用Python在word文档中创建表格

如何使用Python在word文档中创建表格 介绍效果代码 介绍 本文将介绍如何使用Python库python-docx在Word文档中创建表格。 效果 插入表格前的word文档&#xff1a; 插入表格后的word文档&#xff1a; 代码 from docx import Document# 加载现有的Word文档 doc Document(…

利安科技上市首日股价大涨:2023营收净利润下滑,募资金额大幅缩水

《港湾商业观察》施子夫 6月7日&#xff0c;宁波利安科技股份有限公司&#xff08;以下简称&#xff0c;利安科技&#xff09;正式在深交所创业板挂牌上市&#xff0c;股票简称为利安科技&#xff0c;股票代码300784。 上市当天&#xff0c;利安科技股价大涨348.76%。 2022年…

高考志愿填报,如何识别兴趣和擅长?

一年一度的高考落下帷幕&#xff0c;是不是就意味着放松了&#xff1f;解放了&#xff1f; 高考志愿填报的重要性&#xff0c;依旧重要&#xff0c;考得好不如报的好。 考分高低固然是关键&#xff0c;而填报高考志愿&#xff0c;才是真正决定人生的一次选择&#xff0c;这一…

vue3 defineComponent + 渲染函数h + 全局注册​

defineComponent 是 Vue 3 中的一个函数&#xff0c;用于定义一个组件。它是 Vue 3 的组合式 API 的一部分&#xff0c;提供了一种更加灵活和组织化的方式来定义组件。在 Vue 2 中&#xff0c;我们通常使用一个对象来定义组件&#xff0c;而在 Vue 3 中&#xff0c;defineCompo…

Python深度学习基于Tensorflow(17)基于Transformer的图像处理实例VIT和Swin-T

文章目录 VIT 模型搭建Swin-T 模型搭建参考 这里使用 VIT 和 Swin-T 在数据集 cifar10 上进行训练 VIT 模型搭建 导入需要的外部库 import numpy as np import tensorflow as tf import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec这里我们接着使用 ci…

idea开发工具清除Git凭证(含Git凭证管理策略)

前言 网上很多人出现这个问题&#xff0c;也有很多文章或博客来说明这个问题&#xff0c;但是几乎都没有说到点子上&#xff0c;全网几乎都说清除credential.helper配置或者清空windows凭证管理器&#xff0c;还有一些文章说清除IDEA缓存&#xff0c;其实都是不对的。 creden…

我在地球学Python基础第一篇:计算机组成原理基本知识和编程语言基础知识

业精于勤荒于嬉&#xff0c;行成于思毁于随。 今天开始系统记录学习Python 第一篇 计算机组成原理一、什么是计算机二、计算机是由什么组成的&#xff1f;2.1 硬件系统2.2 软件系统 三、计算机如何处理程序&#xff1f;四、编程语言 计算机组成原理 学习目标&#xff1a; 1、…

【docker实战】如何上传镜像到自己的私有仓库

上一篇文章讲了【docker实战】如何登陆到自己的私有仓库&#xff1f; – 经云的清净小站 (skycreator.top)。那么后面的工作就是如何上传镜像到自己的私有仓库了。 下面的操作是使用docker login命令成功之后的操作&#xff0c;没有login请先login。 我打算将本地的ubuntu:18…

攻防演练之-网络安全产品大巡礼二

书接上文&#xff0c;《网络安全攻防演练风云》专栏之攻防演练之-网络安全产品大巡礼一&#xff0c;这里。 “咱们中场休息一会&#xff0c;我去接杯水哈”&#xff0c;看着认真听讲的众人&#xff0c;王工很是满意&#xff0c;经常夹在甲乙两方受气的他&#xff0c;这次终于表…

在Spring Boot中使用Sa-Token实现路径拦截和特定接口放行

在Spring Boot中使用Sa-Token实现路径拦截和特定接口放行 很喜欢的一段话&#xff1a;别想太多&#xff0c;好好生活&#xff0c;也许日子过着过着就会有答案&#xff0c;努力走着走着就会有温柔的着落。 春在路上&#xff0c;花在枝上&#xff0c;所有的美好都在路上&#xff…

Coap协议在物联网中的实战

1. 前言 提到CoAP不能不提MQTT协议&#xff0c;MQTT协议可以保持长链接&#xff0c;具有一定的实时性&#xff0c;云端向客户端发送消息&#xff0c;设备端可以在最短的时间内接收并作出响应&#xff0c;所以MQTT更适合于实时控制场景&#xff0c;需要保持长连接&#xff0c;不…

WDF驱动开发-I/O请求的处理(三)

创建框架请求对象 框架请求对象表示 I/O 管理器已发送到驱动程序的 I/O 请求。 基于框架的驱动程序通过调用 框架请求对象方法来处理每个 I/O 请求。 每个 I/O 请求都包含一个 WDM I/O 请求数据包 (IRP 结构) &#xff0c;但基于框架的驱动程序通常不需要访问 IRP 结构。 大…

【AI大模型】Transformers大模型库(八):大模型微调之LoraConfig

目录 一、引言 二、LoraConfig配置参数 2.1 概述 2.2 LoraConfig参数说明 2.3 代码示例 三、总结 一、引言 这里的Transformers指的是huggingface开发的大模型库&#xff0c;为huggingface上数以万计的预训练大模型提供预测、训练等服务。 &#x1f917; Transformers …