【C++】字串
在【C++】字元與字元陣列 中已經介紹了C語言中形式的字串,這裡再進行深入介紹。
目錄
字串一般共有三種形式
1)字元陣列
char buf[] = "hello";
2)char* 指標
char* str = "hello, world!"
這種有毒,我是vs2017,我使用2)這種方式就給我報錯,必須使用3)這種方式。
3)字串常量
const char* str = "hello, world!"
2)和3)都是字元指標,以上三種列印字串的方式為
printf("%s", buf);
printf("%s", str);
字串和陣列最關鍵的得知道2個資訊:首地址,長度
為什麼C風格字串不需要指定長度?
C風格字串不需要另外製定長度,因為規定了結束字元。
字串遍歷
程式功能:遍歷列印字元,其實就是列印字串
#include "stdio.h" int show_string(const char* str) { for (int i=0; ; i++) { char ch = str[i]; if (ch == 0) { break; } printf("%c", ch); } return 0; } int main() { const char* str = "Hello World!"; printf("%s", str); char buf[] = "hello world!"; printf("%s\n", buf); const char* str1 = "I am nick."; show_string(str1); return 0; }
字串長度如何計算
字串長度:是指從頭開始,一直到結束符,中間的字元的個數。(人為規定)
char str[16] = {'q','w','e',0,'r','t','y',}該字串長度為3;
char str[128] = {0,'q','w','e',0,'r','t','y',}該字串長度為0。
#include "stdio.h" int get_length(const char* str) { int i = 0; while (str[i]) i++; return i; } int main() { const char* str1 = "I am nick."; int str_length = get_length(str1); printf("%d", str_length); return 0; } /* //run out 10 */
字串複製
複製字串,是指將一個字串的內容複製到目標字串,包括結束符。(結束符之後的無效資料不被複制)
複製不是指標的改變,而是記憶體中出現了兩份相同的字串。
#include "stdio.h"
int main()
{
//第一種方式
char src[] = "hello";
char dst[128];
int i = 0;
while (src[i])
{
dst[i] = src[i];
i++;
}
dst[i] = 0;
printf("%s",dst);
//第二種方式
char src_1[] = "hello";
char dst_1[128];
int j = 0;
while (1)
{
dst_1[j] = src_1[j];
if (dst_1[j] == 0) break;
j++;
}
printf("%s", dst_1);
return 0;
}
字串比較
比較方法:逐個字元依次比較,當所有字元全部相同時才認為兩者相等。
#include "stdio.h"
int main()
{
char input[128];
scanf_s("%s", input, 10);
if (input == "yes")//這比較的是2個地址,永遠也不會相等。所以要想比較這兩個字串,必須一個一個字元的比較。
{
printf("OK");
}
else
{
printf("Cancel");
}
return 0;
}
其結果永遠為“Cancel”,永遠也不會相等,你這比較的是2個地址。所以要想實現字串比較,只能一個一個字元的比較。
預設規定:單個字元比較大小,小於返回-1,等於返回0,大於返回1。
#include "stdio.h"
int compare_char(char a, char b)
{
if (a < b)
return -1;
else if (a == b)
return 0;
else
return 1;
}
int main()
{
char input[128];
scanf_s("%s", input, 10);
char candidate[] = "yes";
int i = 0;
while (1)
{
int mark = compare_char(input[i], candidate[i]);
if (mark != 0)
{
printf("Cancel");
break;
}
if(input[i] == 0 && candidate[i] == 0)
{
printf("OK");
break;
}
i++;
}
return 0;
}
刪除字元
從一個字串中刪除一個或多個字元。
從字串中間刪除一個字元,那麼成本很高。比如字串"hello",刪除字元‘e’,那麼就需要將'e'後面的字元都向前移動一個。
程式功能:刪除一個字元。
#include "string.h"
void erase(char text[], int index)
{
int len = strlen(text);
for (int i = index; i < len; i++)
{
text[i] = text[i + 1];
}
}
int main()
{
char str[10] = "hello";
erase(str, 1);
return 0;
}
程式功能:字串中刪除'a'字元。(所有的'a'都需要刪除)
#include "stdio.h"
#include "string.h"
void erase_argument(char text[], char del)
{
int size = strlen(text);
char* final_text = (char*)malloc(size+1); //需要加一個結束符0
int count = 0;
for (int i = 0; i < size; i++)
{
if (text[i] == del)
{
continue;
}
final_text[count] = text[i];
count++;
}
final_text[count] = 0;
strcpy(text, final_text);
free(final_text);
}
int main()
{
char str_1[] = "Hello, Nancy, would you like tom?";
erase_argument(str_1, 'o');
return 0;
}
插入字元
向一個字串中間插入字元。
include "string.h"
void insert_char(char text[], int index, char ins)
{
int len = strlen(text);
for (int i=len; i>index; i--)
{
text[i] = text[i - 1];
}
text[index] = ins;
}
int main()
{
char str[10] = "hello";
insert_char(str, 2, 'P');
return 0;
}
字串分割
頭部:首地址
尾部:結束符
中間有若干個字元
程式功能:修改指定索引的字元。
int main()
{
char str_1[] = "Hello world!";
str_1[3] = 'P';
return 0;
}
小結:char str_1[]申明的字串是可以修改的,char* str_1申明的字串不能修改。具體可以參考部落格
直接利用首地址
我們要了解到str_1是該字串的首地址,所以str_1+1表示第二個字元的地址,所以可以使用如下方式能得到新的字串:
char* str = str_1+1;
程式功能:將字串"Hello world"分割為"Hello"和"world"2個字串。
int main()
{
char str[] = "Hello world";
str[5] = 0;
char* part_0 = str;
char* part_1 = str + 6;
return 0;
}
小結:新增一個結束符,然後直接分割開就好。
程式功能:通用字串分割,分割符號為','和'\0'和' '和'\t'
#include "string.h"
int split(char text[], char* parts[])
{
int count = 0; //分段的個數
int start = 0; //每一分段的首地址
int flag = 0; //遍歷text,標識當前是否處於有效字元
int stop = 0; //是否到達結束
for (int i=0; !stop; i++)
{
char ch = text[i];
if (ch == 0)
{
stop = 1; //停止迴圈
}
if (ch == ',' || ch == '\0' || ch == ' ' || ch == '\t')
{
if (flag)
{
flag = 0;
text[i] = 0;
parts[count] = text + start;
count++;
}
}
else
{
if (!flag)
{
flag = 1;
start = i;
}
}
}
return count;
}
void my_split(char text[], char* parts[])
{
int count = 0;
int start = 0;
int flag = 0; //flag記錄是否進入下一段字串
int size = strlen(text);
for (int i=0; i <= size; i++) //這裡一定是<=,不然結束符取不到就會有問題
{
char ch = text[i];
if (ch == ',' || ch == ' ' || ch == '\t' || ch == '\0') //這裡'\0'是為了找到最後的結束符,不然程式最後一個字串就不能正常結束。
{
if (flag) //這裡特別容易漏。這步的作用是防止連續的 分隔符 截斷合理的分割
{
text[i] = 0; //插入結束符
parts[count] = text + start; //找到起始位置
flag = 0;
count += 1;
}
}
else
{
if (!flag)
{
start = i;
flag = 1;
}
}
}
}
int main()
{
char test_str[] = "Hello, my name is nick";
char* parts[16];
split(test_str, parts);
char test_str_1[] = "Hello, my name is nick";
char* parts_1[16];
my_split(test_str_1, parts_1);
return 0;