现在万事俱备,只欠东风,我们应该着手解决问题了。如果读到此处已经忘记了问题是什么,那么请回顾第一节。
尽管下面这段代码看上去挺丑,但是它能够解决问题。
gboolean is_right_at_sign = TRUE;
glong offset = g_utf8_strlen(demo_text, -1);
gchar *viewer = g_utf8_offset_to_pointer(demo_text, offset - 1);
while (viewer != demo_text) {
viewer = g_utf8_prev_char(viewer);
gchar *utf8_char = get_utf8_char(viewer);
if (!is_space(utf8_char)) {
if (!is_line_break(utf8_char)) {
is_right_at_sign = FALSE;
g_free(utf8_char);
break;
} else {
g_free(utf8_char);
break;
}
}
g_free(utf8_char);
}
if (is_right_at_sign) g_print("Right @ !n");
对上述代码略做简化,可得:
gboolean is_right_at_sign = TRUE;
glong offset = g_utf8_strlen(demo_text, -1);
gchar *viewer = g_utf8_offset_to_pointer(demo_text, offset - 1);
while (viewer != demo_text) {
viewer = g_utf8_prev_char(viewer);
gchar *utf8_char = get_utf8_char(viewer);
if (!is_space(utf8_char)) {
if (!is_line_break(utf8_char)) is_right_at_sign = FALSE;
g_free(utf8_char);
break;
}
g_free(utf8_char);
}
if (is_right_at_sign) g_print("Right @ !n");
其实,如果将 UTF-8 字符的提取与内存释放过程置入 is_space 与 is_line_break 函数,即:
static gboolean is_space(const gchar *c) {
gboolean ret = FALSE;
gchar *utf8_char = get_utf8_char(c);
char *space_chars_set[] = {" ", "t", " "};
size_t n = sizeof(space_chars_set) / sizeof(space_chars_set[0]);
for (size_t i = 0; i < n; i++) {
if (!strcmp(utf8_char, space_chars_set[i])) {
ret = TRUE;
break;
}
}
g_free(utf8_char);
return ret;
}
static gboolean is_line_break(const gchar *c) {
gboolean ret = FALSE;
gchar *utf8_char = get_utf8_char(c);
if (!strcmp(utf8_char, "n")) ret = TRUE;
g_free(utf8_char);
return ret;
}
可以得到进一步的简化结果:
gboolean is_right_at_sign = TRUE;
glong offset = g_utf8_strlen(demo_text, -1);
gchar *viewer = g_utf8_offset_to_pointer(demo_text, offset - 1);
while (viewer != demo_text) {
viewer = g_utf8_prev_char(viewer);
if (!is_space(viewer)) {
if (!is_line_break(viewer)) is_right_at_sign = FALSE;
break;
}
}
if (is_right_at_sign) g_print("Right @ !n");
附:完整的代码
#include <string.h>
#include <glib.h>
gchar *demo_text =
"我的 C81 每天都在口袋里n"
" @";
static gchar * get_utf8_char(const gchar *base) {
gchar *new_base = g_utf8_next_char(base);
gsize n = new_base - base;
gchar *utf8_char = g_memdup(base, (n + 1));
utf8_char[n] = '