我在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*
谢谢。
答案 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