十七、C++字元串(二)

来源:https://www.cnblogs.com/piaolaipiaoqu/archive/2023/11/25/17855601.html
-Advertisement-
Play Games

十七、C++字元串(二) 1、字元串的應用 需求:設計一個程式,用戶輸入屬性id或者pass或者role可以把對應的內容顯示出來,給定字元串如下: string str{"id=user;pass=632105;role=郝英俊;"}; //設計一個程式,用戶輸入屬性id或者pass或者role可以 ...


十七、C++字元串(二)

1、字元串的應用

需求:設計一個程式,用戶輸入屬性id或者pass或者role可以把對應的內容顯示出來,給定字元串如下:

string str{"id=user;pass=632105;role=郝英俊;"};


//設計一個程式,用戶輸入屬性id或者pass或者role可以把對應的內容顯示出來
#include <iostream>
#include <string>
using std::string;
int main()
{
    string str{ "id=user;pass=632105;role=郝英俊;" };
    string strIn;
    string outPut;

    while (true)
    {
        std::cout << "請輸入你要查找的屬性:";
        std::cin >> strIn;
        int lfind;    //find()函數查找的值是一個整數,不是字元串
        lfind = str.find(strIn + "=");
        if (lfind == std::string::npos)std::cout << "你查找的屬性不存在";
        else
        {
            int lend = str.find(";",lfind);
           outPut = str.substr(lfind + strIn.length() + 1, lend - lfind - strIn.length() - 1);
            std::cout << "你查找的" << strIn << "屬性的值為:" << outPut << std::endl;
        }
    }
}

2、string函數補充

1)string插入字元串

.insert()是string類型的一個方法,可以在string字元串的指定位置插入另一個字元串,基本語法如下:

//插入字元串基本語法
.insert(要插入的位置,要插入的字元串);
string id{"id=;"}
id.insert(3,"testid");    //在第3個字元的位置插入字元串testid,最後id的值為id=testid

//插入字元串的高級用法
.insert(要插入的位置,要插入的字元個數,要插入的字元);
string id{"id=;"}
id.insert(3,6,'*');   //在第3個位置插入6個*號,最後id的值為id=******
//insert()字元串插入函數基本用法
#include <iostream>
#include <string>
using std::string;

int main()
{
	string strA { "id=;" };
	strA.insert(3, "user");
	std::cout << "字元串strA插入後的字元串為:" << strA << std::endl;

	string strB{ "id=;" };
	strB.insert(3,6,'*');  //此處插入的是字元,不是字元串,所以要使用單引號
	std::cout << "字元串strB插入後的字元串為:" << strB << std::endl;

}

2)insert插入字元串的擴展用法

//insert()擴展用法語法
.insert(要插入的位置,要插入的字元串,要插入的字元串的起始位置,要插入的大小);
string id{"id=;"};
id.insert(3,"killertestid123456",6,6);  //id=testis

.insert(要插入的位置,要插入的字元串,要插入的大小);
string id{"id=;"};
id.insert(3,"killertestid123456",6);  //id的值為id=killer  從開始位置截取6個字元
//insert()擴展用法示例
#include <iostream>
#include <string>
using std::string;

int main()
{
	string strA{ "id=;" };
    //在原字元串的第三個位置開始插入,插入的內容為此處字元串的第6個位置開始截取,截取6個
	strA.insert(3, "killertestid123456", 6, 6);
	std::cout << "字元串strA插入後的字元串為:" << strA << std::endl;

	string strB{ "id=;" };
     //在原字元串的第三個位置開始插入,插入的內容為此處字元串的第0個位置開始截取,截取6個
	strB.insert(3, "killertestid123456", 6);  //此處插入的是字元,不是字元串,所以要使用單引號
	std::cout << "字元串strB插入後的字元串為:" << strB << std::endl;

}

3、指針數組字元串

1)string字元串不是一個單純的指針或者數組

#include <iostream>
#include <string>
using std::string;
int main()
{
	string str{ "12345" };
	std::cout << "字元串中第1個字元的值為:" << str[0] << std::endl;
	std::cout << "字元串中第2個字元的值為:" << str[1] << std::endl;
	std::cout << "字元串中第3個字元的值為:" << str[2] << std::endl;
	std::cout << "字元串的地址為:" << (int)&str << std::endl;
	std::cout << "str[0]的地址為:" << (int)&str[0] << std::endl;
	std::cout << "str[0]的地址為:" << (int)&str[1] << std::endl;
	
	str = str + "abcdesdajhdhjakd";
	std::cout << "字元串長度增加後的地址為:" << (int)&str << std::endl;
	std::cout << "字元串長度增加後str[0]的地址為:" << (int)&str[0] << std::endl;
	std::cout << "字元串長度增加後str[0]的地址為:" << (int)&str[1] << std::endl;
}
/*結果顯示:
如果str的地址和str[0]的地址一致,說明str相當於一個數組
但是str的地址和str[0]的地址不一樣,說明str不是一個簡單的數組,
從str[0]的地址開始,地址才是連續的
當字元串長度增加後,str的地址不變,但是str[0]開始,後面的每個字元的地址都會變化
*/

2)獲取string字元串的指針

​ 在記憶體里的佈局,與C字元串(char*)不同的是,C字元串以0結尾,而string字元串由於專門記錄其長度的屬性,在實現的時候,並沒有嚴格要求是否以0結尾。但是在C++11標準推出後,要求string字元串也以0結尾

​ 通過.c_str()方法可以得到一個const char*的指針指向str儲存字元數據的記憶體空間(返回的是一個常量指針,只能寫不能讀)

​ 通過.data()方法可以得到一個const char*的指針指向str儲存字元數據的記憶體空間

​ 在c++17標準下,.data()方法得到的是一個char*的指針

#include <iostream>
#include <string>
using std::string;
int main()
{
	string str{ "12345" };

	const char* baseStrA = str.c_str();
	const char* baseStrB = str.data();
	std::cout << "字元串的地址為:" << (int)&str << std::endl;
	std::cout << "通過c_str獲取的字元串地址為為:" << (int)baseStrA << std::endl;
	std::cout << "通過c_str獲取的字元串地址為為:" << (int)baseStrB << std::endl;

}

3)string替換字元串的內容

​ .replace是string類型提供的一種方法,可以替換string字元串中的內容。語法如下

//replace()字元串替換語法
.replace(要替換的內容起始位置,要替換的程度,"替換後的內容");
string str{"id=user;"};
str.replace{3,4,"zhangsan"}; //從原字元串的第三個位置開始,替換四個字元,替換內容為新的字元串

//replace()其他語法
.replace(要替換的內容起始位置,要替換的長度,替換後的字元長度,'字元');
str.replace(3,4,6,'*'); //str的內容為:id=******
//replace()字元串替換函數基本用法
#include <iostream>
#include <string>
using std::string;

int main()
{
	string strA{ "id=user;" };
	//在原字元串的第3個位置開始替換,替換後面的4個字元
	strA.replace(3, 4, "zhangsan");
	std::cout << "字元串strA替換後的字元串為:" << strA << std::endl;

	string strB{ "id=user;" };
	//在原字元串的第3個位置開始替換,替換後面的4個字元,並替換為6個*號
	strB.replace(3, 4, 6, '*');  //此處插入的是字元,不是字元串,所以要使用單引號
	std::cout << "字元串strB替換後的字元串為:" << strB << std::endl;
}

4)replace()函數的擴展用法

//replace()函數的擴展語法
.replace(要替換的內容起始位置,要替換的長度,"替換後的內容",替換後內容的節選長度);
string str{"id=user;"};
str.replace(3,4,"zhangsan;pass=255;",8); //str=zhangsan

//replace()函數的擴展語法
.replace(要替換的內容起始位置,要替換的長度,"替換後的內容",替換後內容的起始位置,替換後內容的節選長度);
string str{"id=user;"};
str.replace(3,4,"zhangsan;pass=255;",5,3); //str=san;
#include <iostream>
#include <string>
using std::string;

int main()
{
	string strA{ "id=user;" };
	//在原字元串的第3個位置開始替換,替換後面的4個字元
	strA.replace(3, 4, "zhangsan;pass=255;", 8); 
	std::cout << "字元串strA替換後的字元串為:" << strA << std::endl;

	string strB{ "id=user;" };
	strB.replace(3, 4, "zhangsan;pass=255;", 5, 3);  
	std::cout << "字元串strB替換後的字元串為:" << strB << std::endl;
}

5)字元串的刪除

​ erase()是string類型提供的一種方法,可以刪除string字元串中的內容,語法如下:

//字元串的刪除erase()函數語法一
.erase(要刪除的起始位置,要刪除的起始長度);
string str{"id=user;"};
str.erase(3,4);   //std為id=;

//從起始位置開始刪除所有內容
.erase(要刪除的起始位置);
string str{"id=user;"};
str.erase(3);   //std為id=

.earse();刪除字元串所有內容
.clear();刪除字元串所有內容
4、字元串補充

1)字元的存儲及讀取

​ 字元串再C/C++的學習中一直是一個比較麻煩的點,但是只要知道"電腦中萬物皆數字",則所有的問題都可以迎刃而解。

​ 字元的存儲:先通過編碼表轉化為數子,再把數字轉化為二進位進行存儲(字元->編碼表->二進位數字)

​ 字元的讀取:先把二進位數字讀取出來,再根據編碼表轉化為字元(二進位數字->編碼表->字元)

​ 字元編碼表:ASCII、GBK、UNICODE

2)練習

​ 需求:設計一個程式,要求用戶輸入中英文混合內容,正確的計算出長度並顯示出來。比如用戶輸入:你好,我的世界。結果輸出為7。

​ 思路:因為字元的ASCII碼範圍為0-127,只要超過127就表明是一個中文字元

#include <iostream>
#include <string>
using std::string;
int main()
{
	string strIn{};
	std::cout << "請輸入計算長度的字元串:";
	std::cin >> strIn;
	int length{};
	for (int i = 0; strIn[i]; i++)
	{
		if (strIn[i] < 0)i++;
		length++;
	}
	std::cout << "你輸入的字元串長度為:" << length << std::endl;
}

2)string字元串轉化為數字

通過std::to_string(數字)可以將數字轉化為字元串。通過一下函數可以將字元串轉化為數字

作用 語法 用法
將字元串轉化為int std::stoi(字元串) int a=stoi("123")
將字元串轉化為long std::stol(字元串) long a=stol("123")
將字元串轉化為long long std::stoll(字元串) long long a=stoll("123");
將字元串轉化為unsigned long std::stoul(字元串) unsigned long a=stoul("123")
將字元串轉化為unsigned long long std::stoull(字元串) unsigned long long a=stoull("123")
將字元串轉化為float std::stof(字元串) float a=stof("123")
將字元串轉化為double std::stod(字元串) double a=stod("123")
將字元串轉化為long double std::stold(字元串) long double a=stold("123")

將字元串轉化為數字後,可以進行計算

#include <iostream>
#include <string>
using std::string;
int main()
{
	string strIn{};
	std::cout << "請輸入計算長度的字元串:";
	std::cin >> strIn;
	int length{};
	for (int i = 0; strIn[i]; i++)
	{
		if (strIn[i] < 0)i++;
		length++;
	}
	std::cout << "你輸入的字元串長度為:" << length << std::endl;
}

3)stringstream流

​ std::stringstream流定義在<sstream>頭文件中,std::cout組織數據的形式有時候要比string字元串要方便。std::stringstream可以像std::cout一樣組織數據。std::stringstream.str()方法將會返回一個string,裡面是std::stringstream的內容,即將流中的內容提取出來

//stringstream流語法
std::stringstream str;
str<<"你好"<<123;
std::string _str=str.str();  //_str的內容為"你好123"
//stringstream流簡單使用
#include <iostream>
#include <string>
#include <sstream>
using std::string;

int main()
{
	std::stringstream strA;
	strA << "你好 [" << std::hex << 500 << "]   "<<std::dec<<123;
	string strB = strA.str();
	std::cout << strB;
}

5、游戲麟江湖排行榜設計

​ 需求:我們通過網路獲得了麟江湖游戲玩家的數據,現在我們要為我們的游戲設計一個戰力(exp)排行榜系統,排序貴u則為戰力由高到低,當戰力相同時,根據ID的字母順序進行排序(如A要排在B的前面)數據如下:

"id=TomyClare;exp=9523;id=Sunny;exp=9523;id=DyBaby;exp=25301;id=Simple;exp=25301;id=Bkacs11;exp=2100;id=DumpX;exp=36520;"

​ 根據這個數據生成玩家排行榜!

#include <iostream>
#include <string>
using std::string;

typedef struct Role 
{
	string Id;
	int Exp;
}*PROLE;

int main()
{
	string strData{ "id=TomyClare;exp=9523;id=Sunny;exp=9523;id=DyBaby;exp=25301;id=Simple;exp=25301;id=Bkacs11;exp=2100;id=DumpX;exp=36520;" };
	int istart{}, iend{}, icount{};
	for (int i = 0; i < strData.length(); i++)
	{
		if (strData[i] == ';')
		{
			icount++;
			i += 3;
		}
	}
	PROLE pRole = new Role[icount / 2];
	icount = 0;
	do 
	{
		istart = strData.find("id=", istart);
		if (istart == std::string::npos) break;
		iend = strData.find(";", istart + 3);
		pRole[icount].Id = strData.substr(istart + 3, iend - istart - 3);
		istart = iend + 1;
		istart = strData.find("exp=", istart);
		iend = strData.find(";", istart + 4);
		pRole[icount++].Exp = std::stoi(strData.substr(istart + 4, iend - istart - 4));
		istart = iend + 1;
	} while (true);
	
	//冒泡排序
	for (int i = 1; i < icount; i++)
	{
		for (int j = 1; j < icount; j++)
		{
			if (pRole[j].Exp > pRole[j - 1].Exp)
			{
				Role tmp = pRole[j - 1];
				pRole[j- 1] = pRole[j];
				pRole[j] = tmp;

			}
		}
	}
	for (int i = 1; i < icount; i++)
	{
		std::cout << pRole[i].Id << "  " << pRole[i].Exp << std::endl;
	}
}


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 事件匯流排是對發佈-訂閱模式的一種實現。 發佈-訂閱模式定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,所有依賴於它的對象都將得到通知。 發佈-訂閱模式實現了松耦合,發佈者不是直接將消息發送給訂閱者,而是經過了一個中間的代理,事件匯流排就是一種中間代理的實現。 ...
  • matplotlib是基於python生態開發的一個可視化繪圖庫,它的出現讓python在數據分析及機器學習方面占了重要的一部分,目前很多數據分析及機器學習相關方面的工程都有使用到這個庫,並且由於其簡單易用,安裝簡單等方面的優勢深得廣大開發者的喜愛。 ...
  • 15.1、常用組件 15.1.1、 DispatcherServlet DispatcherServlet 是前端控制器,由框架提供,不需要工程師開發; 作用:統一處理請求和響應,整個流程式控制制的中心,由它調用其它組件處理用戶的請求。 15.1.2、HandlerMapping HandlerMapp ...
  • 前言: 在Spring Boot中實現快遞鳥、順豐和快遞100的物流查詢功能通常需要與它們提供的API進行交互。當然使用他們的API 我們是需要申請和註冊,從而去拿到 key 來進行調用。所以為註冊的必須先進行註冊,以下是他們的官網地址,可以快捷到達。 快遞鳥官網:快遞鳥 - 快遞查詢介面_免費快遞 ...
  • SQLite,作為一款嵌入式關係型資料庫管理系統,一直以其輕量級、零配置以及跨平臺等特性而備受青睞。不同於傳統的資料庫系統,SQLite是一個庫,直接與應用程式一同編譯和鏈接,無需單獨的資料庫伺服器進程,實現了資料庫的零配置管理。這種設計理念使得SQLite成為許多嵌入式系統、移動應用和小型項目中的... ...
  • 操作系統 :CentOS 7.6_x64 FreeSWITCH版本 :1.10.9 python版本:3.9.12 libpcap版本:1.11.0b7 FreeSWITCH的ESL模塊用起來很方便,可以控制FreeSWITCH實現具體業務需求,但該模塊沒有提供ESL命令執行日誌,不便於排查問題,本 ...
  • 在本期文章中,我們深入探討了Python的對象繼承、組合以及多態這三個核心概念。從繼承的靈活性,如Python的多重繼承和super關鍵字的使用,到組合中的動態屬性添加,我們逐一解析了Python與Java在這些方面的相似之處和差異。通過具體的例子,我們展示了Python中多態的直觀表現,強調了它與... ...
  • API成批分配漏洞介紹API 特定:可利用性 2 利用通常需要瞭解業務邏輯、對象關係和 API 結構。 在 API 中利用批量分配更容易,因為按照設計,它們公開了應用程式的底層實現以及屬性名稱。安全弱點: 現代框架鼓勵開發人員使用自動將客戶端輸入綁定到代碼變數和內部對象的函數。 攻擊者可以使用這種方 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...