我正在读取一个URL(这是一个字符串)并搜索一个模式(连续出现/
个字符)。如果我找到匹配的模式,我想用一个/
替换它,并按原样复制其余的字符。例如:如果输入字符串是http://www.yahoo.com/
,我需要通过删除额外的http:/www.yahoo.com/
来生成输出/
,因为该字符连续出现两次。
以下是该计划:
int main() {
int i, j;
bool found = false;
unsigned char *str = "http://www.yahoo.com/";
int len = strlen(str);
for (i = 0; i < len - 1; i++) {
if ((str[i] == '/') && (str[i + 1] == '/')) {
found = true;
break;
}
}
if (found) {
for (j = i + 1; j <= (len - i - 2); j++) {
str[j] = str[j + 1];
}
}
return 0;
}
但是这个程序正在产生分段错误。这段代码中的问题在哪里?知道怎么解决吗?对此有任何替代的简单实现吗?
答案 0 :(得分:1)
您可能无法更改字符串文字。它们在C和C ++中是不可修改的。根据C标准(6.4.5字符串文字)
7未指明这些阵列是否与它们不同 元素具有适当的值。 如果程序尝试 修改这样的数组,行为是未定义的。
使用标准C函数strstr
可以轻松完成任务。例如
char s[] = "http://www.yahoo.com/";
puts(s);
char *p = strstr(s, "//");
if (p) memmove(p, p + 1, strlen(s) - (p - s));
puts(s);
代码段的输出看起来像
http://www.yahoo.com/
http:/www.yahoo.com/
至于你的程序,那么除了尝试更改字符串文字这个循环是错误的
if (found) {
for(j = i + 1; j <= (len - i - 2); j++) {
str[j] = str[j + 1];
}
}
它应该至少看起来像
if (found) {
for(j = i + 1; j < len; j++) {
str[j] = str[j + 1];
}
}
答案 1 :(得分:0)
您正在使用字符串文字,这是只读内存。当您尝试修改字符时,会出现错误。
将您的字符串数据复制到可写内存中,然后您可以修改它。
最简单的改变就是建立这一行:
unsigned char *str = "http://www.yahoo.com/";
请改为:
char str[] = "http://www.yahoo.com/";
但是,对于C ++,您应该使用std::string
代替,然后您可以使用标准搜索算法,如下所示:
#include <string>
int main() {
std::string str = "http://www.yahoo.com/";
std::string::size_type i = 0;
do {
i = str.find("//", i);
if (i == std::string::npos) break;
str.erase(i, 1);
}
while (!str.empty());
return 0;
}
可替换地:
#include <string>
#include <algorithm>
bool isBackslashPair(const char c1, const char c2) {
return ((c1 == '/') && (c2 == '/'));
}
int main() {
std::string str = "http://www.yahoo.com/";
std::string::iterator iter = str.begin();
do {
iter = std::adjacent_find(iter, str.end(), isBackslashPair);
if (iter == std::string::end()) break;
iter = str.erase(iter);
}
while (!str.empty());
return 0;
}