使用 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;
}
为了自学 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;
}