D语言字符串替换函数优化:空字符串和边界处理

本文分析并优化了一个D语言字符串替换函数replaceString,重点解决了原代码中可能出现的空字符串和边界问题,并详细解释了优化思路和代码实现。

原代码问题

原代码在处理空字符串和边界情况时存在潜在问题,例如:

  • 未对输入参数进行空指针检查,可能导致程序崩溃。
  • 未处理搜索字符串为空的情况,可能导致死循环。
  • 使用strcpy函数时未考虑内存重叠问题,可能导致数据损坏。

优化后的代码

import core.stdc.stdio:printf;
import core.stdc.string;
import core.stdc.stdlib : malloc, free;
import core.stdc.ctype:tolower;

// 判断两个字符是否相等,根据 isCaseSensitive 参数决定是否区分大小写
bool charEqual(char a, char b, bool isCaseSensitive)   @nogc nothrow
{
    if (isCaseSensitive)
    {
        return a == b;
    }
    else
    {
        return tolower(a) == tolower(b);
    }
}

// 在字符串 haystack 中查找第一次出现 needle 的位置,返回指向该位置的指针,如果找不到则返回 null
char* strstrCase(char* haystack, const char* needle, bool isCaseSensitive)   @nogc nothrow
{
    if (!haystack || !needle || !*needle)
    {
        return haystack;
    }

    size_t haystackLen = strlen(haystack);
    size_t needleLen = strlen(needle);

    if (needleLen > haystackLen)
    {
        return null;
    }

    for (size_t i = 0; i <= haystackLen - needleLen; i++)
    {
        bool found = true;
        for (size_t j = 0; j < needleLen; j++)
        {
            if (!charEqual(haystack[i + j], needle[j], isCaseSensitive))
            {
                found = false;
                break;
            }
        }
        if (found)
        {
            return haystack + i;
        }
    }

    return null;
}

// 替换字符串
char* replaceString(char* allStr, const char* searchStr, const char* replaceStr, bool isCaseSensitive)  @nogc nothrow
{
    if (!allStr || !searchStr || !replaceStr || !*searchStr)
    {
        return allStr;
    }

    char* result = null;

    ulong searchStrLength = strlen(searchStr);
    ulong replaceStrLength = strlen(replaceStr);
    ulong count = 0;
    char* p = allStr;

    while ((p = strstrCase(p, searchStr, isCaseSensitive)) != null)
    {
        count++;
        p += searchStrLength;
    }

    if (count == 0)
    {
        return allStr;
    }

    ulong newStrLength = strlen(allStr) + count * (replaceStrLength - searchStrLength);
    result = cast(char*) malloc(newStrLength + 1);

    char* q = result;
    p = allStr;

    while (count-- > 0)
    {
        char* r = strstrCase(p, searchStr, isCaseSensitive);
        long length = r - p;

        memmove(q, p, length);
        q += length;

        memcpy(q, replaceStr, replaceStrLength);
        q += replaceStrLength;

        p = r + searchStrLength;
    }

    strcpy(q, p);

    return result;
}

void main()
{
    char* allStr = 'hello world World�'.dup.ptr;
    const char* searchStr = 'World';
    const char* replaceStr = 'china';
    bool isCaseSensitive = true;

    char* result = replaceString(allStr, searchStr, replaceStr, isCaseSensitive);
    printf('%s
', result);
    free(result);
} 

优化说明

  1. 空指针检查: 在strstrCasereplaceString函数开头添加了对输入参数的空指针检查,避免因为传入空指针导致程序崩溃。
  2. 空字符串处理: 在strstrCase函数中,如果needle为空字符串,则直接返回haystack;在replaceString函数中,如果searchStr为空字符串,则直接返回allStr
  3. 内存重叠: 使用memmove函数代替strcpy函数,避免因为内存重叠导致数据损坏。
  4. 内存释放: 在main函数中,使用free函数释放replaceString函数返回的内存空间,避免内存泄漏。

总结

通过上述优化,replaceString函数能够更加安全、高效地进行字符串替换操作,避免了原代码中存在的潜在问题。

D语言字符串替换函数优化:空字符串和边界处理

原文地址: https://www.cveoy.top/t/topic/jn3e 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录