简介
字符串是一种非常常见的数据类型,为了便于操作字符串,GLib首先将字符串封装成类似C++ CString对象的一个结构体,又对字符串的一系列操作进行了封装,使用起来非常便捷,又避免了很多内存泄露的风险。
对非封装的简单字符串的处理见通用工具集
章的字符串处理函数
一节。
数据结构
struct GString {
gchar *str; //数据,以null结尾,可以作为普通字符串使用
gsize len; //字符串长度,不包括null字节
gsize allocated_len; //在重新分配之前,本节点所能存储的最大内存长度。已分配内存长度。
};
函数列表
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 ()
函数功能分类
创建
GString * g_string_new ()
GString * g_string_new_len ()
GString * g_string_sized_new ()
释放
gchar * g_string_free ()
GBytes * g_string_free_to_bytes ()
插入
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->str;
格式化
void g_string_vprintf ()
void g_string_append_vprintf ()
void g_string_printf ()
void g_string_append_printf ()
覆盖
GString * g_string_overwrite ()
GString * g_string_overwrite_len ()
拷贝
GString * g_string_assign ()
擦除
GString * g_string_erase ()
截短
GString * g_string_truncate ()
设置长度
GString * g_string_set_size ()
大小写转换
GString * g_string_up ()
GString * g_string_down ()
哈希函数
guint g_string_hash ()
gboolean g_string_equal ()
函数功能说明及综合演示
GString字符串是一种内存随文本长度增加而自动增长的数据结构。其数据结构如下:
struct GString {
gchar *str;
gsize len;
gsize allocated_len;
};
- str:实际存放的字符串,以’\0’结尾
- len:字符串的实际长度,不包括结尾的’\0’
- allocated_len:重新申请内存前分配的内存空间,如果存的字符比这个长度大,将会自动重新申请内存
由于GString包含一个len长度,因此str可以存任何字符,甚至是二进制数据。
创建和释放
创建相关的函数及简介:
//g_string_new将给定的init字符串拷贝到GString内,如果init为空,则创建出的GString是一个包含空字符串的变量。
GString * g_string_new (const gchar *init);
//将指定长度的数据拷贝到GString,由于指定了长度,init可以不以'\0'结尾,中间也允许包含空字符。
//由于本函数执行结束时不以遇到'\0'而结束,因此要求调用者保证init的实际总长度不应该小于len
GString * g_string_new_len (const gchar *init, gssize len);
//如果不想频繁重新申请内存,可以在创建时预留好字节大小。注意,此处已经预留了结尾空字符,如果我们dfl_size为256,则实际上分配的大小是512
GString * g_string_sized_new (gsize dfl_size);
释放相关的函数及简介:
//如果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_examples\glib_gstring\glib_gstring_new_free
#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;
}
运行结果:
string1:hello, len:5, allocated_len:8
string2:hel, len:3, allocated_len:4
string3:, len:0, allocated_len:512
str:hello
bytes: hel
插入和访问
插入
字符串插入函数有很多,可以分为头插、尾插和中间插入三大类。
// 字符串追加,如果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_examples\glib_gstring\glib_gstring_insert
#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;
}
运行结果:
string: pre~in~'sert\pendapp ~end
g_string_append_len不但可以处理字符串中间包含0字符问题,还可以处理只截取某一部分数据的情况,举例如下:
源码见`glib_examples\glib_gstring\glib_gstring_append_len
#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;
}
运行结果:
original string: firsthalf
after append: firsthalflasthalf
格式化
格式化
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_examples\glib_gstring\glib_gstring_printf
#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;
}
运行结果:
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
覆盖-拷贝-擦除-截短-设置长度
覆盖
GString * g_string_overwrite ()
GString * g_string_overwrite_len ()
// 字符串覆盖,如果被覆盖的部分长度不够,则字符串所占内存会自动增加
// 如果带长度,还可以支持中间包括'\0'字符的字符串覆盖
拷贝
GString * g_string_assign ()
// 将一个char*类型的字符串拷贝到GString中,如果字符串原来有内容,则原有内容会被清空,再进行拷贝操作,本函数与strcpy类似,但不必担心空间不足问题
擦除
GString * g_string_erase ()
// 擦除从pos位置开始的len个字符,后面的字符前移
截短
GString * g_string_truncate ()
// 按照指定长度截短字符串,如果len大于实际长度,则字符串仍为实际长度,如果len为0,则相当于清空字符串
设置长度
GString * g_string_set_size ()
// 设置GString长度,如果len小于目前长度,则GString会被截断,如果大于当前长度,则新增加的内存内容不确定。
覆盖-拷贝-擦除-截短-设置长度代码演示程序:
源码见glib_examples\glib_gstring\glib_gstring_multi
#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, "a\0a", 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;
}
运行结果:
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):