十七、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;
}
}