字符串替换C ++中的char指针

时间:2017-01-19 19:25:08

标签: c++

我在C++

中的字符串指针上有一个关于字符串替换的简单问题

我有这段代码:

#include <iostream>

static inline char* duplicate_string(const char* source)
{
    char* res = NULL;
    size_t len;

    if (source == NULL) 
    {
        return NULL;
    }

    len = strlen(source) + 1;
    res = new char[len];
    strncpy(res, source, len);
    return res;
}

char* str_replace(const char* orig, const char* rep, const char* str)
{
    char* buffer = NULL;
    const char* p = NULL;
    const char* remainder = NULL;
    char* res = NULL;
    std::string tmp;

    if(!(p = strstr(str, orig))) {
        res = duplicate_string(str);
        return res;
    }

    tmp.append(str, p - str);
    tmp += rep;

    remainder = p + strlen(orig);

    buffer = new char[strlen(remainder) + 1];
    while ((p = strstr(remainder, orig)) != NULL) {
        strncpy(buffer, remainder, p-remainder);
        buffer[p - remainder] = '\0';
        tmp += buffer;
        tmp += rep;
        remainder = p + strlen(orig);
    }
    tmp += remainder;
    delete[] buffer;
    res = duplicate_string(tmp.c_str());
    return res;
}

int main()
{
    puts(str_replace("%domain%123","%domain%","ANOTHER_DOMAIN"));
}

输出

ANOTHER_DOMAIN

预期

ANOTHER_DOMAIN123

我做错了什么?

使用char指针是必须的,我也必须小心不要让内存泄漏而且我不能使用string,整个代码都写在char*

谢谢。

1 个答案:

答案 0 :(得分:0)

您的代码存在很多问题。首先,str_replace()的第2和第3个参数是向后的。并且您正在使用strstr()错误。而且通常不能正确管理内存。

您声称无法使用std::string,但您的str_replace()代码正在使用std::string作为其tmp变量。并且您正在使用#include <iostream>(即使您实际上并未使用任何内容),因此您可以访问#include <string>。使用std::string::replace()代码变得非常容易实现,例如:

#include <iostream>
#include <string>

std::string str_replace(const std::string &orig, const std::string &str, const std::string &rep)
{
    std::string::size_type i = orig.find(str);
    if (i == std::string::npos)
        return orig;

    std::string tmp(orig);
    do
    {
        tmp.replace(i, str.size(), rep);
        i = tmp.find(str, i+str.size());
    }
    while (i != std::string::npos);

    return tmp;
}

int main()
{
    std::cout << str_replace("%domain%123", "%domain%", "ANOTHER_DOMAIN");
    return 0;
}

输出:

  

ANOTHER_DOMAINANOTHER_DOMAIN123

但是,如果你绝对必须只使用char*而不是std::string来做所有事情,那么尝试更像这样的事情:

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

static inline char* duplicate_string(const char* source)
{
    if (!source)
        return NULL;

    size_t len = strlen(source) + 1;
    char* res = new char[len];
    strncpy(res, source, len);

    return res;
}

char* str_replace(const char* orig, const char* str, const char* rep)
{
    if (!orig)
        return NULL;

    std::size_t str_len = strlen(str);

    const char *p = (str_len > 0) ? strstr(orig, str) : NULL;
    if (!p)
        return duplicate_string(orig);

    std::size_t initial_len = (p - orig);
    std::size_t rep_len = strlen(rep);

    std::size_t len = initial_len;
    do
    {
        len += rep_len;
        p += str_len;
        const char *next = strstr(p, str);
        if (!next)
            break;
        len += (next - p);
        p = next;
    }
    while (true);

    std::size_t remaining_len = strlen(p);
    len += remaining_len;

    char *res = new char[len + 1];
    char *work = res;

    strncpy(work, orig, initial_len);
    work += initial_len;

    p = orig + initial_len;
    do
    {
        strncpy(work, rep, rep_len);
        work += rep_len;

        p += str_len;
        const char *next = strstr(p, str);
        if (!next)
            break;

        len = (next - p);
        strncpy(work, p, len);
        work += len;

        p = next;
    }
    while (true);

    strncpy(work, p, remaining_len);
    work += remaining_len;

    *work = '\0';

    return res;
}


int main()
{
    char *str = str_replace("%domain%%domain%123", "%domain%", "ANOTHER_DOMAIN");
    puts(str);
    delete[] str;

    return 0;
}

输出:

  

ANOTHER_DOMAINANOTHER_DOMAIN123