usr 发表于 2023-6-15 05:02:23

【C】SV高亮显示字符串

本帖最后由 usr 于 2023-6-15 05:05 编辑

6月14号 StoneValley 发布了新版本。在新版本中 svstring.h 线性数据结构库增添了一个函数:strCreateZSearchArrayZ。
这个函数用来查找一个字符串内符合一定模式的所有子串。熟悉算法的同学应该了解这个功能。KMP算法实现了此功能。但是在SV中,实现查找子串功能的函数使用了Z算法。
Z算法也被称作扩展KMP算法。是一种时间效率极高的(O(n))字符串匹配算法。
大家可以去StoneValley的主页查看该函数:https://github.com/coshcage/StoneValley/blob/master/src/svarray.c
此外我将如何配置SV的帖子贴在这里,以供大家参考:https://www.0xaa55.com/thread-27369-1-1.html
说到字符串匹配,不得不提Unix下的grep命令。
echo "The quick brown fox jumps over the lazy dog." | grep "the"
以上命令可以高亮显示echo句子中的所有the。
接下来,我教大家做一个高亮字符串的应用。我把它命名为vrcat。意思是Visual Red Cat。代码如下:

/* vrcat for Visual Red Cat.
* (C) cosh.cage#hotmail.com
* 06/15/2023
*/
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "svstring.h"

int main(int argc, char * argv[])
{
        int ch;
        size_t i = 0, m;
        ARRAY_Z * parrtxt, arrptn, * parr; // 三个ARRAY_Z分别是文本串,模式串和匹配结果串。
       
        if (argc < 2)
                return 0;
        arrptn.pdata = argv; // 模式串为输入参数。
        arrptn.num = strlen(argv); // 模式串的长度。
       
        if (arrptn.num < 1)
                return 0;

        parrtxt = strCreateArrayZ(BUFSIZ, sizeof(char));
        if (NULL == parrtxt)
                return 0;
       
        while (!feof(stdin)) // 以下代码是将stdin所有内容读入parrtxt。
        {
                ch = fgetc(stdin);
                parrtxt->pdata = (UCHART)ch;
                if (++i > strLevelArrayZ(parrtxt))
                        if (NULL == strResizeArrayZ(parrtxt, strLevelArrayZ(parrtxt) + BUFSIZ, sizeof(char)))
                                return 0;
        }
        if (NULL == strResizeArrayZ(parrtxt, i, sizeof(char)))
                return 0;

        parr = strCreateZSearchArrayZ(parrtxt, &arrptn, sizeof(char)); // 使用Z算法查找子串所有出现位置。

        if (NULL != parr)
        {
                BOOL b = FALSE;
                size_t j, k;

                for (j = i = 0; i < strLevelArrayZ(parrtxt) - 1; ++i)
                {
                        if (j[(size_t *)parr->pdata] == i) // 如果出现位置和当前打印位置相匹配。
                        {
                                b = TRUE;
                                k = 0;
                                ++j;
                        }
                        if (b)
                                printf("%s", "\e[31m"); // 打印高亮首部,
                        fputc(parrtxt->pdata, stdout); // 打印字符。
                        if (++k >= strLevelArrayZ(&arrptn))
                        {
                                printf("%s", "\e[0m"); // 打印高亮尾部。
                                b = FALSE;
                        }
                }
                m = parr->num;
                strDeleteArrayZ(parr);
        }

        strDeleteArrayZ(parrtxt);

        return m;
}

运行效果是这样的:

strCreateZSearchArrayZ 函数的执行效率很高,因此vrcat的速率也很快。strCreateZSearchArrayZ函数也能处理wchar_t类型,需要读者自行修改代码。
关于Ubuntu 终端上如何高亮显示字符,我找到的相关资料在这里:https://askubuntu.com/questions/623855/changing-the-text-color-in-ubuntu-terminal
https://misc.flogisoft.com/bash/tip_colors_and_formatting
好了,以上就是本贴的全部内容,欢迎大家下载测试。

tangptr@126.com 发表于 2023-6-15 17:49:05

https://tangptr.com/2022/create-extra-consoles-for-your-program-control-your-extra-console-with-escaping/
在控制台上高亮用的是`ASCII-Escaping`字符序列,需要控制台支持。
此外并非所有编译器都认识`\e`,兼容性起见用`\x1b`。
我之前也写过[类似的东西](https://github.com/Zero-Tang/NoirCvmApi/tree/main/examples/mmio),在虚拟环境里以MMIO的方式写一个模拟控制台,然后虚拟机软件以走命名管道转发给PuTTY。

usr 发表于 2023-6-16 12:38:22

tangptr@126.com 发表于 2023-6-15 17:49
https://tangptr.com/2022/create-extra-consoles-for-your-program-control-your-extra-console-with-esca ...

好的,感谢提醒和参与回复!

tlwh163 发表于 2023-6-16 22:06:09

看不明白你要展示哪种技术 Z算法还是彩色字?
页: [1]
查看完整版本: 【C】SV高亮显示字符串