[英]Replace a string in C without string.h library
我想制作一个 function,它将在不使用<string.h>
库的情况下替换两个字符串。 为了实现这一点,我使用了 6 个手动编写的函数,它们共同完成了这项任务。 这段代码有一个小问题,它不检查将被替换的字符串是否是完全等于替换字符串的单词。
例如:
char s[] = "Why is ostring in C so hard",
change_what[] = "string",
into_what[] = "pointers";
OUTPUT 应该是:
"Why is ostring in C so hard"
因为"ostring"
并不完全等于"string"
。
我的 output 是:
"Why are opointers in C so hard"
代码:
#include <stdio.h>
int compare(char *x, char *y)
{
while (*x != '\0' || *y != '\0')
{
if (*x == *y)
{
x++;
y++;
}
// if they are not equal
else if ((*x == '\0' && *y != '\0') || (*x != '\0' && *y == '\0') ||
*x != *y)
{
return 0;
}
}
return 1;
}
int lenght(char *a)
{
char *b;
for (b = a; *a; a++)
;
return a - b;
}
char *substring(char *main_string, char *substring) {
while (*main_string != '\0') {
char *p = main_string;
char *q = substring;
while (*p++ == *q++) {
if (*p == ' ' || *p == '\0')
if (*q == '\0') {
return main_string;
}
}
main_string++;
}
return NULL;
}
void replace_string_add(char *s, char *change_what, char *into_what,
int shift)
{
char *i_pointer = into_what;
char *c_pointer = change_what;
char *position = substring(s, change_what);
while (position != NULL)
{
char *end = position;
while (*end != '\0')
{
end++;
}
while (end > position)
{
*(end + shift) = *end;
end--;
}
while (*into_what != '\0')
{
*position++ = *into_what++;
}
position = substring(s, change_what);
into_what = i_pointer;
change_what = c_pointer;
}
}
void replace_string_remove(char *s, char *change_what, char *into_what,
int shift)
{
char *i_pointer = into_what;
char *c_pointer = change_what;
char *position = substring(s, change_what);
while (position != NULL)
{
char *temp = position;
while (*(temp + shift) != '\0')
{
*temp = *(temp + shift);
temp++;
}
*temp = '\0';
while (*into_what != '\0')
{
*position++ = *into_what++;
}
position = substring(s, change_what);
into_what = i_pointer;
change_what = c_pointer;
}
}
void replace_string(char *s, char *change_what, char *into_what)
{
int shift = lenght(into_what) - lenght(change_what);
if (compare(change_what, into_what) == 0)
{
if (shift >= 0)
{
replace_string_add(s, change_what, into_what, shift);
}
else
{
replace_string_remove(s, change_what, into_what, -shift);
}
}
}
int main()
{
char s[] = "Why is ostring in C so hard",
change_what[] = "string",
into_what[] = "pointers";
replace_string(s, change_what, into_what);
printf("\"%s\"", s);
return 0;
}
如果字符串是"Why is strings in C so hard"
程序将正确工作,因为它检查最后一个字符是' '
还是'\0'
。
"Why is ostring in C so hard"
是行不通的,因为它不检查第一个字符。 你能帮我修改这段代码来检查第一个字符吗?
您的程序有多个问题:
compare
function里面有很多冗余代码,可以简化为:
int compare(const char *x, const char *y) { while (*x;= '\0' || *y;= '\0') { if (*x == *y) { x++; y++; } else { return 0; } } return 1; }
甚至更进一步:
int compare(const char *x, const char *y) { while (*x++ == *y++) { if (x[-1] == '\0') return 1; } return 0; }
lenght
function 应命名为length
substring
检查 substring 结束后的空格,但不检查开始前的空格。 如果 substring 匹配main_string
的结尾,它也有未定义的行为,因为将访问超出 null 终止符的字符。 这是修改后的版本:
char *substring(char *main_string, const char *substring) { char *p = main_string; char last = ' '; while (*p;= '\0') { if (last == ' ') { size_t i = 0; while (substring[i];= '\0' && p[i] == substring[i]) { i++; } if (substring[i] == '\0' && (p[i] == ' ' || p[i] == '\0')) { return p; } } last = *p++; } return NULL; }
在replace_string_add
和replace_string_remove
中, c_pointer
是无用的,使用i_pointer
复制替换比修改into_what
并恢复它更容易混淆。
另请注意, main_string
参数必须有足够的空间用于替换,如果change_what
字符串为"ostring"
,则示例中不会出现这种情况。
这是修改后的版本:
#include <stdio.h>
int compare(const char *x, const char *y) {
while (*x++ == *y++) {
if (x[-1] == '\0')
return 1;
}
return 0;
}
int length(const char *a) {
const char *b;
for (b = a; *a; a++)
continue;
return a - b;
}
char *substring(char *main_string, const char *substring, int len) {
char *p = main_string;
char last = ' ';
while (*p != '\0') {
if (last == ' ') {
int i = 0;
while (i < len && p[i] == substring[i]) {
i++;
}
if (i == len && (p[i] == ' ' || p[i] == '\0')) {
return p;
}
}
last = *p++;
}
return NULL;
}
char *replace_string(char *s, const char *change_what, const char *into_what) {
int what_len = length(change_what);
int into_len = length(into_what);
int shift = into_len - what_len;
int i;
char *pos = s;
if (shift == 0 && compare(change_what, into_what))
return s;
while (*pos && (pos = substring(pos, change_what, what_len)) != NULL) {
if (shift > 0) {
for (i = length(pos); i >= what_len; i--) {
pos[i + shift] = pos[i];
}
} else
if (shift < 0) {
for (i = into_len; ((pos[i] = pos[i - shift]) != '\0'; i++) {
continue;
}
}
for (i = 0; i < into_len; i++) {
*pos++ = into_what[i];
}
if (*pos == ' ') {
pos++;
}
}
return s;
}
int main() {
char s[100] = "Why is ostring in C so hard";
printf("\"%s\"\n", replace_string(s, "string", "pointer"));
printf("\"%s\"\n", replace_string(s, "ostring", "pointers"));
printf("\"%s\"\n", replace_string(s, "is", "are"));
printf("\"%s\"\n", replace_string(s, "hard", "cool"));
printf("\"%s\"\n", replace_string(s, "pointers", "strings"));
printf("\"%s\"\n", replace_string(s, "in C", ""));
printf("\"%s\"\n", replace_string(s, "", "in C++ not"));
printf("\"%s\"\n", replace_string(s, "", ""));
return 0;
}
Output:
"Why is ostring in C so hard"
"Why is pointers in C so hard"
"Why are pointers in C so hard"
"Why are pointers in C so cool"
"Why are strings in C so cool"
"Why are strings so cool"
"Why are strings in C++ not so cool"
"Why are strings in C++ not so cool"
好的,我认为为此使用字符串标记器更容易。 下面的代码首先将 s 复制到 s2 中,然后在每个空格处放置一个 '\0' 并跟踪有多少个单词。 第一个 for 循环。 然后清除 s 并循环通过 s2 在每个 '\0' 标记处停止并检查每个单词是否等于您的替换词。 如果匹配,则复制回替换词,否则复制原始词。
#include <stdio.h>
static void cat(char *d, char *s)
{
char *p;
for (p = d; *p; p++);
for (char *p2 = s; *p2;)
*p++ = *p2++;
*p = 0;
}
static int cmp(char *s1, char *s2)
{
char *p1 = s1, *p2 = s2;
while (*p1 && *p2 && *p1 == *p2)
{
p1++;
p2++;
}
if (*p1 == 0 && *p2 == 0) return 0;
return -1;
}
int main()
{
char s[100]="Why are strings in C so hard",change_what[]="strings", into_what[]="pointers";
char s2[100];
for (char *p = s, *p2 = s2; *p2=*p; p++, p2++);
int countwords = 0;
for (char *p = s2; *p; p++)
if (*p == ' ') { *p = '\0'; countwords++; }
int current = 0;
char *s3 = s2;
*s = '\0';
while (current <= countwords)
{
char *p = s3;
for (; *p; p++);
if (cmp(s3, change_what) == 0)
cat(s, into_what);
else
cat(s, s3);
cat(s, " ");
s3 = p + 1;
current++;
}
printf("%s\n", s);
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.