這篇文章給大家介紹C語言中怎么動態(tài)擴(kuò)容String,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
站在用戶的角度思考問題,與客戶深入溝通,找到騰沖網(wǎng)站設(shè)計與騰沖網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:網(wǎng)站設(shè)計、成都網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名與空間、雅安服務(wù)器托管、企業(yè)郵箱。業(yè)務(wù)覆蓋騰沖地區(qū)。
首先定義一個string的句柄,相當(dāng)于C++中的實例
struct c_string; typedef struct c_string c_string_t;
在內(nèi)部string的實現(xiàn)如下:
// string的初始內(nèi)存大小 static const size_t c_string_min_size = 32; struct c_string { char *str; // 字符串指針 size_t alloced; // 已分配的內(nèi)存大小 size_t len; // 字符串的實際長度 };
創(chuàng)建字符串:
c_string_t *c_string_create(void) { c_string_t *cs; cs = calloc(1, sizeof(*cs)); cs->str = malloc(c_string_min_size); *cs->str = '\0'; // 初始分配內(nèi)存大小是32,之后每次以2倍大小擴(kuò)容 cs->alloced = c_string_min_size; cs->len = 0; return cs; }
銷毀字符串:
void c_string_destroy(c_string_t *cs) { if (cs == NULL) return; free(cs->str); free(cs); }
內(nèi)部如何擴(kuò)容呢:
static void c_string_ensure_space(c_string_t *cs, size_t add_len) { if (cs == NULL || add_len == 0) return; if (cs->alloced >= cs->len + add_len + 1) return; while (cs->alloced < cs->len + add_len + 1) { cs->alloced <<= 1; // 每次以2倍大小擴(kuò)容 if (cs->alloced == 0) { // 左移到最后可能會變?yōu)?,由于alloced是無符號型,減一則會變成UINT_MAX cs->alloced--; } } cs->str = realloc(cs->str, cs->alloced); }
在尾部追加字符串:
void c_string_append_str(c_string_t *cs, const char *str, size_t len) { if (cs == NULL || str == NULL || *str == '\0') return; if (len == 0) len = strlen(str); c_string_ensure_space(cs, len); // 確保內(nèi)部有足夠的空間存儲字符串 memmove(cs->str + cs->len, str, len); cs->len += len; cs->str[cs->len] = '\0'; }
在尾部追加字符:
void c_string_append_char(c_string_t *cs, char c) { if (cs == NULL) return; c_string_ensure_space(cs, 1); cs->str[cs->len] = c; cs->len++; cs->str[cs->len] = '\0'; }
在尾部追加整數(shù):
void c_string_append_int(c_string_t *cs, int val) { char str[12]; if (cs == NULL) return; snprintf(str, sizeof(str), "%d", val); // 整數(shù)轉(zhuǎn)為字符串 c_string_append_str(cs, str, 0); }
在頭部插入字符串:
void c_string_front_str(c_string_t *cs, const char *str, size_t len) { if (cs == NULL || str == NULL || *str == '\0') return; if (len == 0) len = strlen(str); c_string_ensure_space(cs, len); memmove(cs->str + len, cs->str, cs->len); memmove(cs->str, str, len); cs->len += len; cs->str[cs->len] = '\0'; }
在頭部插入字符:
void c_string_front_char(c_string_t *cs, char c) { if (cs == NULL) return; c_string_ensure_space(cs, 1); memmove(cs->str + 1, cs->str, cs->len); cs->str[0] = c; cs->len++; cs->str[cs->len] = '\0'; }
在頭部插入整數(shù):
void c_string_front_int(c_string_t *cs, int val) { char str[12]; if (cs == NULL) return; snprintf(str, sizeof(str), "%d", val); c_string_front_str(cs, str, 0); }
清空字符串:
void c_string_clear(c_string_t *cs) { if (cs == NULL) return; c_string_truncate(cs, 0); }
裁剪字符串:
void c_string_truncate(c_string_t *cs, size_t len) { if (cs == NULL || len >= cs->len) return; cs->len = len; cs->str[cs->len] = '\0'; }
刪除頭部的N個字符:
void c_string_drop_begin(c_string_t *cs, size_t len) { if (cs == NULL || len == 0) return; if (len >= cs->len) { c_string_clear(cs); return; } cs->len -= len; memmove(cs->str, cs->str + len, cs->len + 1); }
刪除尾部的N個字符:
void c_string_drop_end(c_string_t *cs, size_t len) { if (cs == NULL || len == 0) return; if (len >= cs->len) { c_string_clear(cs); return; } cs->len -= len; cs->str[cs->len] = '\0'; }
獲取字符串的長度:
size_t c_string_len(const c_string_t *cs) { if (cs == NULL) return 0; return cs->len; }
返回字符串指針,使用的是內(nèi)部的內(nèi)存:
const char *c_string_peek(const c_string_t *cs) { if (cs == NULL) return NULL; return cs->str; }
重新分配一塊內(nèi)存存儲字符串返回:
char *c_string_dump(const c_string_t *cs, size_t *len) { char *out; if (cs == NULL) return NULL; if (len != NULL) *len = cs->len; out = malloc(cs->len + 1); memcpy(out, cs->str, cs->len + 1); return out; }
測試代碼如下:
int main() { c_string_t *cs = c_string_create(); c_string_append_str(cs, "123", 0); c_string_append_char(cs, '4'); c_string_append_int(cs, 5); printf("%s \n", c_string_peek(cs)); c_string_front_str(cs, "789", 0); printf("%s \n", c_string_peek(cs)); c_string_drop_begin(cs, 2); printf("%s \n", c_string_peek(cs)); c_string_drop_end(cs, 2); printf("%s \n", c_string_peek(cs)); c_string_destroy(cs); return 0; }
輸出:
12345 78912345 912345 9123
完整代碼如下:頭文件:
#include <stddef.h> struct c_string; typedef struct c_string c_string_t; c_string_t *c_string_create(void); void c_string_destroy(c_string_t *cs); void c_string_append_str(c_string_t *cs, const char *str, size_t len); void c_string_append_char(c_string_t *cs, char c); void c_string_append_int(c_string_t *cs, int val); void c_string_front_str(c_string_t *cs, const char *str, size_t len); void c_string_front_char(c_string_t *cs, char c); void c_string_front_int(c_string_t *cs, int val); void c_string_clear(c_string_t *cs); void c_string_truncate(c_string_t *cs, size_t len); void c_string_drop_begin(c_string_t *cs, size_t len); void c_string_drop_end(c_string_t *cs, size_t len); size_t c_string_len(const c_string_t *cs); const char *c_string_peek(const c_string_t *cs); char *c_string_dump(const c_string_t *cs, size_t *len);
源文件:
#include <ctype.h> #include <stdbool.h> #include <stdlib.h> #include <stdio.h> #include <string.h> static const size_t c_string_min_size = 32; struct c_string { char *str; size_t alloced; size_t len; }; c_string_t *c_string_create(void) { c_string_t *cs; cs = calloc(1, sizeof(*cs)); cs->str = malloc(c_string_min_size); *cs->str = '\0'; cs->alloced = c_string_min_size; cs->len = 0; return cs; } void c_string_destroy(c_string_t *cs) { if (cs == NULL) return; free(cs->str); free(cs); } static void c_string_ensure_space(c_string_t *cs, size_t add_len) { if (cs == NULL || add_len == 0) return; if (cs->alloced >= cs->len + add_len + 1) return; while (cs->alloced < cs->len + add_len + 1) { cs->alloced <<= 1; if (cs->alloced == 0) { cs->alloced--; } } cs->str = realloc(cs->str, cs->alloced); } void c_string_append_str(c_string_t *cs, const char *str, size_t len) { if (cs == NULL || str == NULL || *str == '\0') return; if (len == 0) len = strlen(str); c_string_ensure_space(cs, len); memmove(cs->str + cs->len, str, len); cs->len += len; cs->str[cs->len] = '\0'; } void c_string_append_char(c_string_t *cs, char c) { if (cs == NULL) return; c_string_ensure_space(cs, 1); cs->str[cs->len] = c; cs->len++; cs->str[cs->len] = '\0'; } void c_string_append_int(c_string_t *cs, int val) { char str[12]; if (cs == NULL) return; snprintf(str, sizeof(str), "%d", val); c_string_append_str(cs, str, 0); } void c_string_front_str(c_string_t *cs, const char *str, size_t len) { if (cs == NULL || str == NULL || *str == '\0') return; if (len == 0) len = strlen(str); c_string_ensure_space(cs, len); memmove(cs->str + len, cs->str, cs->len); memmove(cs->str, str, len); cs->len += len; cs->str[cs->len] = '\0'; } void c_string_front_char(c_string_t *cs, char c) { if (cs == NULL) return; c_string_ensure_space(cs, 1); memmove(cs->str + 1, cs->str, cs->len); cs->str[0] = c; cs->len++; cs->str[cs->len] = '\0'; } void c_string_front_int(c_string_t *cs, int val) { char str[12]; if (cs == NULL) return; snprintf(str, sizeof(str), "%d", val); c_string_front_str(cs, str, 0); } void c_string_clear(c_string_t *cs) { if (cs == NULL) return; c_string_truncate(cs, 0); } void c_string_truncate(c_string_t *cs, size_t len) { if (cs == NULL || len >= cs->len) return; cs->len = len; cs->str[cs->len] = '\0'; } void c_string_drop_begin(c_string_t *cs, size_t len) { if (cs == NULL || len == 0) return; if (len >= cs->len) { c_string_clear(cs); return; } cs->len -= len; /* +1 to move the NULL. */ memmove(cs->str, cs->str + len, cs->len + 1); } void c_string_drop_end(c_string_t *cs, size_t len) { if (cs == NULL || len == 0) return; if (len >= cs->len) { c_string_clear(cs); return; } cs->len -= len; cs->str[cs->len] = '\0'; } size_t c_string_len(const c_string_t *cs) { if (cs == NULL) return 0; return cs->len; } const char *c_string_peek(const c_string_t *cs) { if (cs == NULL) return NULL; return cs->str; } char *c_string_dump(const c_string_t *cs, size_t *len) { char *out; if (cs == NULL) return NULL; if (len != NULL) *len = cs->len; out = malloc(cs->len + 1); memcpy(out, cs->str, cs->len + 1); return out; }
關(guān)于C語言中怎么動態(tài)擴(kuò)容String就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
文章標(biāo)題:C語言中怎么動態(tài)擴(kuò)容String
標(biāo)題來源:http://www.rwnh.cn/article40/gdgceo.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供Google、網(wǎng)站設(shè)計公司、網(wǎng)站營銷、手機(jī)網(wǎng)站建設(shè)、品牌網(wǎng)站制作、定制網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)