目前共有6篇帖子。
【原創函數】C語言字元串的連接,插入和替換函數
1樓 巨大八爪鱼 2015-12-19 19:09
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *str_create(const char *str)
{
    int len = strlen(str);
    char *pStr = (char *)calloc(len + 1, sizeof(char));
    if (pStr != NULL)
        strcpy(pStr, str);
    return pStr;
}

int str_concat(char **p, const char *str)
{
    int oldlen = strlen(*p);
    int len = strlen(str);
    int newsize = oldlen + len + 1;
    char *q = realloc(*p, newsize * sizeof(char));
    if (q == NULL)
        return 0;
    *p = q;
    strcpy(*p + oldlen, str);
    return 1;
}

int str_insert(char **p, const int pos, const char *str)
{
    int oldlen = strlen(*p);
    int len = strlen(str);
    int newsize = oldlen + len + 1;
    char *q = realloc(*p, newsize * sizeof(char));
    if (q == NULL)
        return 0;
    *p = q;
    memmove(*p + pos + len, *p + pos, oldlen - pos + 1);
    memcpy(*p + pos, str, len);
    return 1;
}

int str_replace_once(const char *find, const char *replace, char **p)
{
    char *ch = strstr(*p, find);
    int newsize, oldlen, flen, rlen, pos;
    char *q;
    if (ch == NULL)
        return 0;
    
    pos = ch - *p;
    oldlen = strlen(*p);
    flen = strlen(find);
    rlen = strlen(replace);
    newsize = oldlen - flen + rlen + 1;
    q = realloc(*p, newsize * sizeof(char));
    if (q == NULL)
        return 0;
    *p = q;
    ch = *p + pos;
    memmove(ch + rlen, ch + flen, oldlen - pos - flen + 1); // including \0 at the end
    memcpy(ch, replace, rlen);
    return 1;
}

int str_replace(char *find, char *replace, char **p)
{
    int count = 0;
    while (str_replace_once(find, replace, p))
        count++;
    return count;
}

int str_reset(char **p, const char *newstr)
{
    int len = strlen(newstr);
    char *q = realloc(*p, (len + 1) * sizeof(char));
    if (q == NULL)
        return 0;
    *p = q;
    strcpy(*p, newstr);
    return 1;
}

int main(int argc, char *argv[])
{
    char *str = str_create("abcdef"); // str = "abcdef"
    int count;
    
    puts(str);
    str_concat(&str, "123456"); // str += "123456"
    puts(str);
    str_insert(&str, 2, "CD");
    puts(str);
    str_replace_once("f1", "{mine}", &str);
    puts(str);
    
    str_reset(&str, "ababababca"); // str = "ababababc"
    puts(str);
    count = str_replace("b", "?", &str);
    puts(str);
    printf("Replacement count: %d\n", count);
    count = str_replace("a", "{you}", &str);
    puts(str);
    printf("Replacement count: %d\n", count);
    
    str_insert(&str, 0, "The result is "); // str = str + ...
    str_concat(&str, ".");
    puts(str);
    
    free(str);
    return 0;
}
2樓 巨大八爪鱼 2015-12-19 19:10
【運行結果】
abcdef
abcdef123456
abCDcdef123456
abCDcde{mine}23456
ababababca
a?a?a?a?ca
Replacement count: 4
{you}?{you}?{you}?{you}?c{you}
Replacement count: 5
The result is {you}?{you}?{you}?{you}?c{you}.
3樓 巨大八爪鱼 2015-12-19 19:18
【函數列表】
char *str_create(const char *str)
在堆內存中根據str的長度動態申請一塊內存並存儲該字元串。失敗則返回NULL。

int str_concat(char **p, const char *str)
將字元串p的空間延長後,在尾部與字元串str連接。成功時返回1,失敗時返回0。

int str_insert(char **p, const int pos, const char *str)
在指定位置pos插入字元串str,並將後續內容往後挪動。成功時返回1,失敗時返回0。

int str_replace_once(const char *find, const char *replace, char **p)
把字元串p中的find字元串替換為replace字元串,只替換一次。成功時返回1,失敗時返回0。

int str_replace(char *find, char *replace, char **p)
把字元串p中的所有find字元串全部替換為replace字元串。返回成功替換的個數。注意replace字元串裡面不要包含find字元串,否則該函數會無法結束而陷入無窮迴圈。

int str_reset(char **p, const char *newstr)
將字元串p的內容重新賦值,並自動調整所佔內存大小。
4樓 巨大八爪鱼 2015-12-19 19:20
【說明】
由於C++語言中已經有了很強大的string類,所以電腦上可能並不會用到這些函數。不過這些函數可以在單片機中使用,因為在單片機C語言程序中包含一個字元串庫文件會使得生成的hex文件迅速增大。
6樓 巨大八爪鱼 2015-12-19 19:30
【補充函數】
int str_replace_nth(char *find, char *replace, char **p, int n)
{
    int count = 0;
    while (n-- && str_replace_once(find, replace, p))
        count++;
    return count;
}
該函數可以指定替換字元串的次數。
比如替換兩次:
str_reset(&str, "ababababca");
count = str_replace_nth("a", "{you}", &str, 2);
puts(str);
printf("Replacement count: %d\n", count);
輸出:
{you}b{you}bababca
Replacement count: 2
請注意,代碼中的&&兩邊條件的位置不能互換,也不能把n--改為--n。
7樓 巨大八爪鱼 2015-12-19 19:32
最後,在程序結束時,一定要記得執行free(str)釋放內存空間!

回復帖子

內容:
用戶名: 您目前是匿名發表
驗證碼:
 
 
©2010-2025 Arslanbar [手機版] [桌面版]
除非另有聲明,本站採用創用CC姓名標示-相同方式分享 3.0 Unported許可協議進行許可。