我是靠谱客的博主 真实眼睛,这篇文章主要介绍4_01_GLib库入门与实践_字符串,现在分享给大家,希望可以做个参考。

简介

字符串是一种非常常见的数据类型,为了便于操作字符串,GLib首先将字符串封装成类似C++ CString对象的一个结构体,又对字符串的一系列操作进行了封装,使用起来非常便捷,又避免了很多内存泄露的风险。
对非封装的简单字符串的处理见通用工具集章的字符串处理函数一节。

数据结构

复制代码
1
2
3
4
5
6
struct GString { gchar *str; //数据,以null结尾,可以作为普通字符串使用 gsize len; //字符串长度,不包括null字节 gsize allocated_len; //在重新分配之前,本节点所能存储的最大内存长度。已分配内存长度。 };

函数列表

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
GString * g_string_new () GString * g_string_new_len () GString * g_string_sized_new () GString * g_string_assign () void g_string_vprintf () void g_string_append_vprintf () void g_string_printf () void g_string_append_printf () GString * g_string_append () GString * g_string_append_c () GString * g_string_append_unichar () GString * g_string_append_len () GString * g_string_append_uri_escaped () GString * g_string_prepend () GString * g_string_prepend_c () GString * g_string_prepend_unichar () GString * g_string_prepend_len () GString * g_string_insert () GString * g_string_insert_c () GString * g_string_insert_unichar () GString * g_string_insert_len () GString * g_string_overwrite () GString * g_string_overwrite_len () GString * g_string_erase () GString * g_string_truncate () GString * g_string_set_size () gchar * g_string_free () GBytes * g_string_free_to_bytes () GString * g_string_up () GString * g_string_down () guint g_string_hash () gboolean g_string_equal ()

函数功能分类

创建

复制代码
1
2
3
4
GString * g_string_new () GString * g_string_new_len () GString * g_string_sized_new ()

释放

复制代码
1
2
3
gchar * g_string_free () GBytes * g_string_free_to_bytes ()

插入

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
GString * g_string_append () GString * g_string_append_c () GString * g_string_append_unichar () GString * g_string_append_len () GString * g_string_append_uri_escaped () GString * g_string_prepend () GString * g_string_prepend_c () GString * g_string_prepend_unichar () GString * g_string_prepend_len () GString * g_string_insert () GString * g_string_insert_c () GString * g_string_insert_unichar () GString * g_string_insert_len ()

访问

复制代码
1
2
GString->str;

格式化

复制代码
1
2
3
4
5
void g_string_vprintf () void g_string_append_vprintf () void g_string_printf () void g_string_append_printf ()

覆盖

复制代码
1
2
3
GString * g_string_overwrite () GString * g_string_overwrite_len ()

拷贝

复制代码
1
2
GString * g_string_assign ()

擦除

复制代码
1
2
GString * g_string_erase ()

截短

复制代码
1
2
GString * g_string_truncate ()

设置长度

复制代码
1
2
GString * g_string_set_size ()

大小写转换

复制代码
1
2
3
GString * g_string_up () GString * g_string_down ()

哈希函数

复制代码
1
2
3
guint g_string_hash () gboolean g_string_equal ()

函数功能说明及综合演示

GString字符串是一种内存随文本长度增加而自动增长的数据结构。其数据结构如下:

复制代码
1
2
3
4
5
6
struct GString { gchar *str; gsize len; gsize allocated_len; };
  • str:实际存放的字符串,以’’结尾
  • len:字符串的实际长度,不包括结尾的’’
  • allocated_len:重新申请内存前分配的内存空间,如果存的字符比这个长度大,将会自动重新申请内存

由于GString包含一个len长度,因此str可以存任何字符,甚至是二进制数据。

创建和释放

创建相关的函数及简介:

复制代码
1
2
3
4
5
6
7
8
9
10
//g_string_new将给定的init字符串拷贝到GString内,如果init为空,则创建出的GString是一个包含空字符串的变量。 GString * g_string_new (const gchar *init); //将指定长度的数据拷贝到GString,由于指定了长度,init可以不以''结尾,中间也允许包含空字符。 //由于本函数执行结束时不以遇到''而结束,因此要求调用者保证init的实际总长度不应该小于len GString * g_string_new_len (const gchar *init, gssize len); //如果不想频繁重新申请内存,可以在创建时预留好字节大小。注意,此处已经预留了结尾空字符,如果我们dfl_size为256,则实际上分配的大小是512 GString * g_string_sized_new (gsize dfl_size);

释放相关的函数及简介:

复制代码
1
2
3
4
5
6
//如果free_segment为TRUE,则内存会自动释放,如果free_segment为FALSE,则会返回字符串的地址,此时需要调用者自行释放内存。 gchar * g_string_free (GString *string, gboolean free_segment); //将一个GString对象转换成GBytes对象,GString对象销毁,但其所指内存空间不会消失,需要在GBytes对象处自行释放。 GBytes * g_string_free_to_bytes (GString *string);

字符串创建和释放的示例代码如下:
源码见glib_examplesglib_gstringglib_gstring_new_free

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <glib.h> gint main(gint argc, gchar **argv) { GString *string1, *string2, *string3; char *str = NULL; GBytes *bytes = NULL; gconstpointer data = NULL; gsize size = 0; string1 = g_string_new("hello"); string2 = g_string_new_len("hello", 3); string3 = g_string_sized_new(256); g_print("string1:%s, len:%d, allocated_len:%d n", string1->str, (gint)string1->len, (gint)string1->allocated_len); g_print("string2:%s, len:%d, allocated_len:%d n", string2->str, (gint)string2->len, (gint)string2->allocated_len); g_print("string3:%s, len:%d, allocated_len:%d n", string3->str, (gint)string3->len, (gint)string3->allocated_len); str = g_string_free(string1, FALSE); g_print("str:%s n", str); g_free(str); bytes = g_string_free_to_bytes(string2); data = g_bytes_get_data(bytes, &size); g_print("bytes: %s n", (gchar *)data); g_bytes_unref(bytes); g_string_free(string3, TRUE); return 0; }

运行结果:

复制代码
1
2
3
4
5
6
string1:hello, len:5, allocated_len:8 string2:hel, len:3, allocated_len:4 string3:, len:0, allocated_len:512 str:hello bytes: hel

插入和访问

插入
字符串插入函数有很多,可以分为头插、尾插和中间插入三大类。

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 字符串追加,如果GString内存不足,则会自动扩展 GString * g_string_append () //追加一个字符 GString * g_string_append_c () //Unicode转utf-8并存入GString,更多字符集转换见Unicode Manipulation GString * g_string_append_unichar () //将len个字节的长度追加到GString,val中可能包含空字符 GString * g_string_append_len () GString * g_string_prepend () GString * g_string_prepend_c () GString * g_string_prepend_unichar () GString * g_string_prepend_len () GString * g_string_insert () GString * g_string_insert_c () GString * g_string_insert_unichar () GString * g_string_insert_len ()

访问
GString字符串的访问没有专门函数,可以直接访问其结构体成员变量
Gstring->str;

下面是插入和访问的代码示例:
源码见glib_examplesglib_gstringglib_gstring_insert

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <glib.h> gint main(gint argc, gchar **argv) { GString *string; gunichar wc = 0x007E; string = g_string_sized_new(256); g_string_append(string, "app"); g_string_append_c(string, 't'); g_string_append_unichar(string, wc); g_string_append_len(string, "end", 3); g_string_prepend(string, "pend"); g_string_prepend_c(string, '\'); g_string_prepend_unichar(string, wc); g_string_prepend_len(string, "pre", 3); g_string_insert(string, 4, "sert"); g_string_insert_c(string, 4, '''); g_string_insert_unichar(string, 4, wc); g_string_insert_len(string, 4, "in", 2); g_print("string: %s n", string->str); g_string_free(string, TRUE); return 0; }

运行结果:

复制代码
1
2
string: pre~in~'sertpendapp ~end

g_string_append_len不但可以处理字符串中间包含0字符问题,还可以处理只截取某一部分数据的情况,举例如下:
源码见`glib_examplesglib_gstringglib_gstring_append_len

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <glib.h> gint main(gint argc, gchar **argv) { GString *string; string = g_string_new ("firsthalf"); g_print("original string: %s n", string->str); g_string_append_len (string, "lasthalfjunkjunk", strlen ("lasthalf")); g_print("after append: %s n", string->str); // value is firsthalflasthalf g_string_free (string, TRUE); return 0; }

运行结果:

复制代码
1
2
3
original string: firsthalf after append: firsthalflasthalf

格式化

格式化

复制代码
1
2
3
4
5
void g_string_printf () void g_string_append_printf () void g_string_vprintf () void g_string_append_vprintf ()

g_string_printf,类似于sprintf,但不需要考虑内存越界问题。且如果原字符串有内容,则原内容会自动清空。
g_string_append_printf,和g_string_printf相似,但只是追加,不会清空原有内容。
g_string_vprintf、g_string_append_vprintf和前面两个类似,不过参数是var_args。
代码举例如下:
源码见glib_examplesglib_gstringglib_gstring_printf

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#include <glib.h> static void _string_vprintf (GString *string, const gchar *format, ...) { va_list args; va_start (args, format); g_string_vprintf (string, format, args); va_end (args); } static void _string_append_vprintf (GString *string, const gchar *format, ...) { va_list args; va_start (args, format); g_string_append_vprintf (string, format, args); va_end (args); } gint main(gint argc, gchar **argv) { GString *string; string = g_string_new("hello"); g_print("string: %s n", string->str); g_string_printf(string, "new str %s %d", "world", 100); g_print("printf string: %s n", string->str); g_string_append_printf(string, "%s %s %d", "==", "append str", 200); g_print("append printf string: %s n", string->str); _string_vprintf(string, "%s %d", "foo", 300); g_print("vprintf string: %s n", string->str); _string_append_vprintf(string, "%s %d", "-append vprintf ", 400); g_print("append vprintf string: %s n", string->str); g_string_free(string, TRUE); return 0; }

运行结果:

复制代码
1
2
3
4
5
6
string: hello printf string: new str world 100 append printf string: new str world 100== append str 200 vprintf string: foo 300 append vprintf string: foo 300-append vprintf 400

覆盖-拷贝-擦除-截短-设置长度

覆盖

复制代码
1
2
3
4
5
GString * g_string_overwrite () GString * g_string_overwrite_len () // 字符串覆盖,如果被覆盖的部分长度不够,则字符串所占内存会自动增加 // 如果带长度,还可以支持中间包括''字符的字符串覆盖

拷贝

复制代码
1
2
3
GString * g_string_assign () // 将一个char*类型的字符串拷贝到GString中,如果字符串原来有内容,则原有内容会被清空,再进行拷贝操作,本函数与strcpy类似,但不必担心空间不足问题

擦除

复制代码
1
2
3
GString * g_string_erase () // 擦除从pos位置开始的len个字符,后面的字符前移

截短

复制代码
1
2
3
GString * g_string_truncate () // 按照指定长度截短字符串,如果len大于实际长度,则字符串仍为实际长度,如果len为0,则相当于清空字符串

设置长度

复制代码
1
2
3
GString * g_string_set_size () // 设置GString长度,如果len小于目前长度,则GString会被截断,如果大于当前长度,则新增加的内存内容不确定。

覆盖-拷贝-擦除-截短-设置长度代码演示程序:
源码见glib_examplesglib_gstringglib_gstring_multi

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <glib.h> gint main(gint argc, gchar **argv) { GString *string; string = g_string_new("hello"); g_print("ori string: %s n", string->str); g_string_overwrite(string, 1, "aaa"); g_print("overwrite(1) string: %s n", string->str); g_string_overwrite_len(string, 1, "aa", 3); g_print("overwrite_len(1,3)string(len:%d): %s n", (gint)string->len, string->str); g_string_printf(string, "%s", "aabbccdd"); g_string_assign(string, "abcd"); g_print("assign string(len:%d): %s n", (gint)string->len, string->str); g_string_truncate(string, 2); g_print("truncate(2) string(len:%d): %s n", (gint)string->len, string->str); g_string_truncate(string, 0); g_print("truncate(0) string(len:%d): %s n", (gint)string->len, string->str); g_string_printf(string, "%s", "aabbccdd"); g_string_erase(string, 2, 4); g_print("erase(2,4) string(len:%d): %s n", (gint)string->len, string->str); g_string_truncate(string, 0); g_print("truncate(0) string(len:%d): %s n", (gint)string->len, string->str); g_string_set_size(string, 8); g_print("set_size(8)string(len:%d): %s n", (gint)string->len, string->str); g_string_free(string, TRUE); return 0; }

运行结果:

复制代码
1
2
3
4
5
6
7
8
9
10
ori string: hello overwrite(1) string: haaao overwrite_len(1,3)string(len:5): ha assign string(len:4): abcd truncate(2) string(len:2): ab truncate(0) string(len:0): erase(2,4) string(len:4): aadd truncate(0) string(len:0): set_size(8)string(len:8):

最后

以上就是真实眼睛最近收集整理的关于4_01_GLib库入门与实践_字符串的全部内容,更多相关4_01_GLib库入门与实践_字符串内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(99)

评论列表共有 0 条评论

立即
投稿
返回
顶部