C语言中的find- replace字符串函数

n3h0vuf2  于 2023-06-28  发布在  其他
关注(0)|答案(4)|浏览(122)

网上有很多查找/替换功能,但我找不到为什么这不起作用......(我自己的解决方案)以下是我尝试的

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* strrpl(char *str, char* find, char *replace)
{
    int i;
    char *pt = strstr(str, find), *firstStr;

    firstStr = (char* )malloc(100 * sizeof(char));
    // copy just until i find what i need to replace
    // i tried to specify the length of firstStr just with pt - str
    strncpy(firstStr, str, strlen(str) - strlen(pt));  

    strcat(firstStr, replace);
    strcat(firstStr, pt + strlen(find));

    for(i = 0; i < strlen(firstStr); i++)
        str[i] = firstStr[i];
    return str;
}

int main()
{
    char *s, *s1, *s2;
    s = (char* )malloc(100 * sizeof(char));
    s1 = (char* )malloc(100 * sizeof(char));
    s2 = (char* )malloc(100 * sizeof(char));
    scanf("%s", s1);
    scanf("%s", s2);
    scanf("%s", s);

    printf("%s", strrpl(s, s1, s2));
    return 0;
}

编译给了我错误“分割错误”,但我不知道他试图分配什么内存,他不能。我覆盖了一个内存块还是什么?请帮帮忙:)
谢谢

apeeds0o

apeeds0o1#

我覆盖了一个内存块还是什么?
您有:
1.分配firstStr时可能发生缓冲区溢出。谁说结果会少于100个字符?
1.当您将答案复制回输入字符串时,另一个潜在的缓冲区溢出。谁说它会适合?
1.每次使用scanf时都可能发生缓冲区溢出。
1.每次调用malloc时都会发生内存泄漏。

  1. return str;之前的strcpy的低效实现。
    1.当输入字符串不包含替换字符串时发生的崩溃(形式上,未定义的行为)。strstr返回NULL,如果没有匹配,并且您从不检查它。
  2. strncpy的一个潜在问题是,如果NUL没有足够的空间,字符串就不会以NUL结尾。
qf9go6mv

qf9go6mv2#

现在的问题是:当strstr返回NULL时,您的代码不会注意。添加这一行:

char *pt = strstr(str, find), *firstStr;
if (!pt) return str;

另一个问题是strncpy的调用不正确:

strncpy(firstStr, str, strlen(str) - strlen(pt));

它将保留firstStr未终止,因为str比被复制的子串长。随后的电话

strcat(firstStr, replace);

将对非空终止的字符串进行操作,从而导致未定义的行为。
解决这个问题的“散弹枪”方法是使用calloc而不是malloc将零放入firstStr。更精确的方法是将'\0'放在复制的子字符串的末尾。
有了这些修复,您的代码运行正常(demo)。然而,有几个问题需要解决:

*您没有释放任何您动态分配的资源-这将导致内存泄漏。
*您不计算要分配多少内存-如果在100个字符的字符串中将5个字符的字符串替换为100个字符的字符串,则会使临时缓冲区溢出。
*您使用strncpy不正确-该函数适用于固定长度的字符串。使用memcpy代替。
*您正在使用strcat而不是memcpystrcpy-这是低效的。

pn9klfpd

pn9klfpd3#

您尚未检查strstr的返回值。试试下面的代码。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* strrpl(char *str, char* find, char *replace)
{
    int i;
    char *pt = strstr(str, find);
    char *firstStr;
    if(pt == NULL){
        printf("cannot find string \n");
        return NULL;
    }

    firstStr = (char* )malloc(100 * sizeof(char));

    // copy just until i find what i need to replace
    // i tried to specify the length of firstStr just with pt - str

    strncpy(firstStr, str, strlen(str) - strlen(pt)); 
    strcat(firstStr, replace);
    strcat(firstStr, pt + strlen(find));

    for(i = 0; i < strlen(firstStr); i++)
        str[i] = firstStr[i];
    return str;
}

int main()
{
    char *s, *s1, *s2, *s3;
    s = (char* )malloc(100 * sizeof(char));
    s1 = (char* )malloc(100 * sizeof(char));
    s2 = (char* )malloc(100 * sizeof(char));
    s3 = (char* )malloc(100 * sizeof(char));

    scanf("%s", s);//input string
    scanf("%s", s1);//string to find
    scanf("%s", s2);//string to replace

    s3 = strrpl(s, s1, s2);
    if(s3 != NULL)
        printf("%s \n",s3);

    return 0;
}
ldioqlga

ldioqlga4#

那memmove呢?
假设src在向右移位时足够长:

char *str_rpl(char *src, char *pattern, char *rpl) {
  char *dest, *origin;
  char *found = strstr(src, pattern);
  
  if(!found) {
    return NULL;
  }

  /* Shifting right or left to fit new size */
  dest = found;
  origin = found + strlen(pattern);

  if(strlen(rpl) > strlen(pattern)) {
    dest += strlen(rpl);
  }   
  else {
    origin -= strlen(rpl);
  }   
  memmove(dest, origin, strlen(origin) + 1);

  /* Replacement */
  memcpy(found, rpl, strlen(rpl));

  return found;
}

相关问题