使用 C 字符串查找和替换

Find and Replace with c-strings

为了自学 C,我正在编写一些基本字符串操作函数。我尽量避免使用外部库。

我认为问题出在这个函数上。它应该在 'src' 中搜索 'find' 并将其替换为 'replace'。但是,如果 'find' 位于 'src' 的末尾,则它不起作用。

char* str_find_r(const char* src, const char* find, const char* replace)
{
    int found = str_find(src, find);

    if(found != -1)
    {
        int begin = found;
        int end = found + str_len(find);

        return str_replace(src, replace, begin, end);
    }

    return str_copy(src);
}

代码:

my_string.h

#ifndef _MY_STRING_H_
#define _MY_STRING_H_

#include <stdlib.h>

int     str_compare(const char* str1, const char* str2);
int     str_contains(const char* str, const char* tok);
int     str_find(const char* str, const char* tok);
int     str_len(const char* str);

char*   str_alloc(int length);
char*   str_concat(const char* str1, const char* str2);
char*   str_copy(const char* other);
char*   str_delete(const char* str, int begin, int end);
char*   str_insert(const char* str, const char* tok, int index);
char*   str_replace(const char* str, const char* tok, int begin, int end);
char*   str_substr(const char* str, int begin, int end);

char*   str_find_r(const char* str, const char* find, const char* replace);
char*   str_find_ra(const char* str, const char* find, const char* replace);

#endif

my_string.c

#include "my_string.h"

int str_compare(const char* str1, const char* str2)
{
    int len1 = str_len(str1);
    int len2 = str_len(str2);

    int i;
    int j;  
    for(i = 0, j = 0; i < len1, j < len2; i++, j++)
    {
        char c1 = str1[i];
        char c2 = str2[j];

        if(c1 == c2)
        {
            continue;
        }
        else
        {
            if(c1 < c2)
            {
                return -1;
            }
            else
            {
                return 1;
            }
        }
    }

    return 0;
}

int str_contains(const char* str, const char* tok)
{
    int len_str = str_len(str);
    int len_tok = str_len(tok);

    int i;  
    for(i = 0; i < len_str - len_tok; i++)
    {
        char* substr = str_substr(str, i, i + len_tok);
        int compare = str_compare(substr, tok);

        if(str_compare(substr, tok) == 0)
        {
            return 1;
        }
    }

    return 0;
}

int str_find(const char* str, const char* tok)
{
    int len_str = str_len(str);
    int len_tok = str_len(tok);

    int i;  
    for(i = 0; i < len_str - len_tok; ++i)
    {
        char* substr = str_substr(str, i, i + len_tok);
        int compare = str_compare(substr, tok);

        if(compare == 0)
        {
            return i;
        }
    }

    return -1;
}

int str_len(const char* str)
{
    int length = 0;

    while(str[length] != '[=12=]')
    {
        length++;
    }

    return length;
}


char* str_alloc(int length)
{
    char* str = malloc(sizeof(char) * length);

    return str;
}

char* str_concat(const char* str1, const char* str2)
{
    int len1 = str_len(str1);
    int len2 = str_len(str2);
    int len3 = len1 + len2;

    char* str3 = str_alloc(len3);

    int i = 0;
    for(i = 0; i < len1; i++)
    {
        str3[i] = str1[i];
    }

    int j = 0;
    for(j = 0; j < len2; j++)
    {
        str3[j + i] = str2[j];
    }

    return str3;
}

char* str_copy(const char* other)
{
    int len = str_len(other);
    char* copy = str_alloc(len);

    int i;
    for(i = 0; i < len; i++)
    {
        copy[i] = other[i];
    }

    return copy;

}

char* str_delete(const char* str, int begin, int end)
{
    char* str1 = str_substr(str, 0, begin);
    char* str2 = str_substr(str, end, str_len(str));

    return str_concat(str1, str2);

}

char* str_insert(const char* str1, const char* str2, int index)
{
    char* lhs = str_substr(str1, 0, index);
    char* rhs = str_substr(str1, index, str_len(str1));

    return str_concat(str_concat(lhs, str2), rhs);
}

char* str_replace(const char* str1, const char* str2, int begin, int end)
{
    char* del = str_delete(str1, begin, end);

    return str_insert(del, str2, begin);
}

char* str_substr(const char* str, int begin, int end)
{   
    int len = (end - begin);    
    char* substr = str_alloc(len);

    int i, j;
    for(i = begin, j = 0; i < end; i++, j++)
    {
        substr[j] = str[i];
    }

    return substr;
}


char* str_find_r(const char* src, const char* find, const char* replace)
{
    int found = str_find(src, find);

    if(found != -1)
    {
        int begin = found;
        int end = found + str_len(find);

        return str_replace(src, replace, begin, end);
    }

    return str_copy(src);
}

char* str_find_ra(const char* src, const char* find, const char* replace)
{
    char* copy = str_copy(src);

    while(str_contains(copy, find))
    {
        copy = str_find_r(copy, find, replace);
    }

    return copy;
}

存根:

void str_stub()
{
    /// Compare
    int compare = str_compare("a", "b");
    printf("Compare: %i\n", compare);
    /**/

    /// Contains
    int contains = str_contains("Hello, World!", ", ");
    printf("Contains: %i\n", contains);
    /**/

    /// Find String
    int found = str_find("Hello, %s!", "%s");
    printf("Found at %i\n", found);
    /**/

    /// Length
    int len = str_len("Hello, World!");
    printf("Length: %i\n", len);
    /**/


    /// Concat
    char* concat = str_concat("Hello, ", "World!");
    printf("Concat: %s\n", concat);
    /**/

    /// Copy
    char* copy = str_copy("Hello, World!");
    printf("Copy: %s\n", copy);
    /**/

    /// Delete
    char* del = str_delete("Hello, World!", 0, 5);
    printf("Delete: %s\n", del);
    /**/

    /// Insert
    char* insert = str_insert("HelloWorld!", ", ", 5);
    printf("Insert: %s\n", insert);
    /**/

    /// Replace
    char* replace = str_replace("Hello, World!", "Goodbye", 0, 5);
    printf("Replace: %s\n", replace);
    /**/

    /// Substr
    char* substr = str_substr("Hello, World!", 0, 4);
    printf("Substr: %s\n", substr);
    /**/

    /// Find and Replace
    char* find_r = str_find_r("Hello, %s World!", "%s", "#");
    printf("Find-R: %s\n", find_r);
    /**/

    /// Find and Replace All
    char* find_ra = str_find_ra("%sHello, %s World! %s", "%s", "#");
    printf("Find-RA: %s\n", find_ra);
    /**/
}

输出:

Compare: -1
Contains: 1
Found at 7
Length: 13
Concat: Hello, World!
Copy: Hello, World!
Delete: , World!
Insert: Hello, World!
Replace: Goodbye, World!
Substr: Hell
Find-R: Hello, # World!
Find-RA: #Hello, # World! %s

通常我会通过调试来完成,但我在文本编辑器中编写代码并通过终端编译它(我被难住了)。任何帮助将不胜感激。

编辑: 我改变了我的比较功能。仍然得到相同的结果。

int str_compare(const char* str1, const char* str2)
{
    int len1 = str_len(str1);
    int len2 = str_len(str2);   

    int maxLength = len1 < len2 ? len1 : len2;

    int i;
    for (i = 0; i < maxLength; i++)
    {
        char c1 = str1[i];
        char c2 = str2[i];

        if(c1 == c2)
        {
            continue;
        }
        else
        {
            if(c1 < c2)
            {
            return -1;
            }
            else
            {
            return 1;
            }
        }
    }


    return 0;
}
char* str_concat(const char* str1, const char* str2)
{
    int len1 = str_len(str1);
    int len2 = str_len(str2);
    int len3 = len1 + len2;

    char* str3 = str_alloc(len3);

您需要为终止 NUL 字符分配 space,并在构建连接字符串时自行添加。

我 运行 我的代码通过 Visual Studio 调试器,发现它从未真正检查过字符串中的最后一个字符。我增加了 str_find 循环遍历源字符串的次数。我还将每个 malloc 字符串中的最后一个字符设置为 '\0'。

以下是我所做的更改:

int str_contains(const char* str, const char* tok)
{
    int find = str_find(str, tok);

    return find != -1;
}

int str_find(const char* str, const char* tok)
{
    int len_str = str_len(str);
    int len_tok = str_len(tok);

    /*HERE*/
    // Added +1 loops
    int i;
    for(i = 0; i < (len_str - len_tok) + 1; ++i) 
    {
        char* substr = str_substr(str, i, i + len_tok);
        if(str_equals(substr, tok)) 
        {
            return i;
        }
    }

    return -1;
}

int str_equals(const char* str1, const char* str2)
{
    int len1 = str_len(str1);
    int len2 = str_len(str2);

    if(len1 != len2)
    {
        return 0;
    }

    int i;
    for(i = 0; i < len1; i++)
    {
        if(str1[i] != str2[i])
        {
            return 0;
        }
    }

    return 1;
}