1. 程式人生 > >【C++】字串

【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;