字符處理
C
-
特性
-
C語言中字符串存儲在字符數組中,以空字符
'\0'
結束。 -
字符串常量,
const char* str = "Hello"
,存儲在只讀的數據段中。
-
-
布局
-
字符串在內存中是字符連續存儲的集合,最后一個字符為空字符(ASCII值為0),用來標識當前字符串的結束。
-
字符串可以存儲在棧(局部變量)、堆(動態分配)、全局、靜態區等。
-
-
處理
- C標準庫提供的字符串處理函數,
<string.h>
頭文件中,包含了字符串拷貝、拼接、比較、長度、截斷等。
- C標準庫提供的字符串處理函數,
CPP
-
特性
-
C++提供了
std::string
類型,它封裝了字符數組,并且在此基礎上提供了更加豐富的字符串處理業務。 -
std::string
支持內存動態擴容,不需要指定緩沖區大小。
-
-
布局
std::string
內部管理與維護一個動態分配內存大小的指針,用于存儲字符串數據。
-
處理
std::string
是標準模板庫(STL)中的一部分,其實現定義在頭文件<string.h>
中。
串的概念
-
串基本概念
-
串(字符串)是由零個或多個字符組成的有限序列。
-
-
串和線程表
-
線性表指的是元素之間的線性關系,元素之間的物理結構是次要的。
-
串是特殊的線性表,串當中的元素為字符,串整體與字串的關系。
-
-
串存儲結構
-
順序結構
- 順序結構基于一段連續的內存空間來存儲串當中的字符序列。
-
鏈式結構
- 鏈式結構基于鏈表的形式存儲字符串,每個節點可以包含一個或多個字符。
-
塊鏈結構
- 塊鏈結構基于串的分割,每一塊包含一個字符數組,不同的塊通過鏈表關聯。
?
- 塊鏈結構基于串的分割,每一塊包含一個字符數組,不同的塊通過鏈表關聯。
-
串的操作
#include <iostream>namespace str
{// length 字符串長度// str 源字符串int length(const char* str){// 參數校驗if (str == NULL) return -1;// 獲取長度int nLength = 0;while (*(str++) != '\0') nLength++;// 返回結果return nLength;}// Assign 字符串賦值// Dest 目標字符串的緩沖區// Sour 源字符串// DestSize 目標緩沖區的大小void Assign(char* Dest, const char* Sour, size_t DestSize){// 參數校驗if (Dest == NULL || Sour == NULL || DestSize == 0) return;// 內容賦值int nLength = 0;while (*Sour/*源字符串當前下標字符是否為空*/ && nLength < DestSize - 1/*目標緩沖區長度是否滿足*/){//Dest[nLength] = Sour[nLength];*Dest++ = *Sour++;nLength++;}*Dest = '\0';}// Concatenate 字符串拼接// str1 第一個字符串的緩沖區// str2 連接的字符串緩沖區// str1Size 第一個字符串的緩沖區長度void Concatenate(char* str1, const char* str2, size_t str1Size){//參數校驗if (str1 == NULL || str2 == NULL || str1Size == 0) return;//字符長度int str1length = str::length(str1);//字符拼接int i = 0;for (i = 0; str2[i] != '\0' && str1Size - 1 > str1length + i; i++){str1[str1length + i] = str2[i];}//追加標記str1[str1length + i] = '\0';}// SunString 子串提取// Sour 源字符串數據// Dest 提取字符串空間// nDestSize 提取字符串容量 // nStart 提取字符串位置// nCount 提取字符串數量void SubString(const char* Sour, char* Dest, int nDestSize, int nStart, int nCount){//參數校驗if (Sour == NULL || Dest == NULL || nDestSize == 0 || nCount == 0) return;//起始校驗int nSourLength = str::length(Sour);if (nSourLength <= nStart || nStart < 0) return;//長度校驗if (nCount < 0 || nCount > nSourLength - nStart) return;//空間校驗if (nCount >= nDestSize) return;//提取子串int i = 0;for (i = 0; i < nCount; i++){Dest[i] = Sour[nStart + i];}//字符追加Dest[i] = '\0';}// SubPosition 子串查找// Sour 源字符串// Sub 子串內容int SubPosition(const char* Sour, const char* Sub){//參數校驗if (Sour == NULL || Sub == NULL) return -1;//數據備份int nPosition = 0;const char* str_it;const char* sub_it;//算法定位for (str_it = Sour; *str_it != '\0'; str_it++){sub_it = Sub;//數據匹配if (*str_it == *sub_it){const char* str_temp = str_it;//匹配子串while (*str_temp && *sub_it && (*str_temp == *sub_it)){str_temp++, sub_it++;}if (*sub_it == '\0'){return nPosition;}}nPosition++;}return -1;}// Compare 字符串比較// str1 源字符串// str2 目標字符串int Compare(const char* str1, const char* str2){//參數校驗if (str1 == NULL || str2 == NULL) return -1;//字符比較while (*str1 && *str2){if (*str1 == *str2){str1++;str2++;}else{break;}}return *str1 - *str2;}// Insert 字符串插入// str1 源字符串數據// str2 被插入字符串數據// nPos 插入位置索引// size_str1 源字符串緩沖區總大小void Insert(char* str1, const char* str2, int nPos, int size_str1){//參數校驗if (str1 == NULL || str2 == NULL) return;//字符長度int str1len = str::length(str1);int str2len = str::length(str2);//下標越界if (nPos < 0 || nPos > str1len) return;//空間處理if (str1len + str2len + 1 > size_str1) return;//移動空間for (int i = str1len; i >= nPos; i--){str1[i + str2len] = str1[i];}//數據拷貝for (int i = 0; i < str2len; i++){str1[nPos + i] = str2[i];}}// Delete 字符串刪除// str 源字符串數據// nPos 起始刪除位置// nlength 刪除字符長度void Delete(char* str, int nPos, int nlength){//參數校驗if (str == NULL) return;//起始校驗int strlen = str::length(str);if (nPos < 0 || nPos > strlen) return;//刪除校驗if (nlength < 0 || (nPos + nlength) > strlen) return;//位置修正char* Start = str + nPos;char* End = str + nPos + nlength;//數據刪除while (*End){*Start++ = *End++;}*Start = '\0';}// Replace 字符串替換// str 源字符串數據// to_replace 被替換字符串// repalce 替換字符串// size_str 緩沖區長度void Replace(char* str, const char* to_replace, const char* repalce, int size_str){//參數校驗if (str == NULL || to_replace == NULL || repalce == NULL) return;//子串定位int nPos = str::SubPosition(str, to_replace);if (nPos == -1)return;//空間判斷int strlen = str::length(str);int torlen = str::length(to_replace);int replen = str::length(repalce);if (strlen - torlen + replen > size_str) return;//拷貝數據char* pTemp = (char*)malloc(size_str);if (pTemp == NULL)return;memset(pTemp, 0, size_str);//00 00 00 00 00 00 00 00 00 00 00 00 00memcpy(pTemp, str, nPos);//H E L 00 00 00 00 00 00 00 00 00 00memcpy(pTemp + nPos, repalce, replen);//H E L 0 x C C 00 00 00 00 00 00memcpy(pTemp + nPos + replen, str + nPos + torlen, strlen - torlen - nPos);//H E L 0 x C C H E L L O 0memcpy(str, pTemp, size_str);free(pTemp);}// Split 字符串分割// str 源字符串數據// chDelimiter 分隔符// outCount 子串數量char** Split(const char* str, char chDelimiter, int* outCount){//參數校驗if (str == NULL) return NULL;//分割數量int nCount_Delimiter = 1;for (int i = 0; str[i] != '\0'; i++){if (str[i] == chDelimiter) ++nCount_Delimiter;}//寫回數據*outCount = nCount_Delimiter;//分配空間char** strArr = (char**)malloc(nCount_Delimiter * sizeof(char*));if (!strArr) return NULL;memset(strArr, 0, nCount_Delimiter * sizeof(char*));//子串長度int i = 0;int j = 0;int nCount_Word = 0;for (i = 0, nCount_Word = 0; str[i] != '\0'; i++){if (str[i] != chDelimiter){nCount_Word++;}else{strArr[j++] = (char*)malloc(nCount_Word * sizeof(char) + 1);nCount_Word = 0;} }strArr[j] = (char*)malloc(nCount_Word * sizeof(char) + 1);//拷貝數據for (i = 0, j = 0, nCount_Word = 0; str[i]; i++){if (str[i] != chDelimiter){strArr[j][nCount_Word++] = str[i];}else{strArr[j][nCount_Word++] = '\0';j++;nCount_Word = 0;}}strArr[j][nCount_Word++] = '\0';return strArr;}}int main()
{//字符長度const char szBuffer1[50] = "0xCC";int nLength = str::length(szBuffer1);//字符賦值char szBuffer2[4] = { 0 };str::Assign(szBuffer2, "Hello", sizeof(szBuffer2));//字符拼接char szBuffer3[50] = "Hello";str::Concatenate(szBuffer3, "World", sizeof(szBuffer3));//子串提取char szBuffer4[] = "Hello World";char szBuffer5[10] = { 0 };str::SubString(szBuffer4, szBuffer5, sizeof(szBuffer5), 6, 5);//子串查找char szBuffer8[] = "HELHELLHELLO";char szBuffer9[] = "HELLO";str::SubPosition(szBuffer8, szBuffer9);//字符比較char szBuffer6[] = "Hel";char szBuffer7[] = "Hel";str::Compare(szBuffer6, szBuffer7);//字符插入char szBuffer10[12] = "Hello";char szBuffer11[] = "0xCC";str::Insert(szBuffer10, szBuffer11, 1, sizeof(szBuffer10));//字符刪除str::Delete(szBuffer10, 1, 4);//字符替換char szBuffer12[] = "HELHELLHELLO";char szBuffer13[] = "HELL";char szBuffer14[] = "CC"; str::Replace(szBuffer12, szBuffer13, szBuffer14, sizeof(szBuffer12));//字符分割int nCount = 0;char szBuffer15[] = "Hello,World,Ferry,0xCC";char** resule = str::Split(szBuffer15, ',', &nCount);return 0;
}