【问题标题】:Replace consecutive duplicate character with its single occurance将连续的重复字符替换为其单次出现
【发布时间】:2016-12-13 01:05:40
【问题描述】:

我正在读取一个 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;
}

但是这个程序正在产生一个分段错误。这段代码的问题在哪里?知道如何解决吗?有任何替代的简单实现吗?

【问题讨论】:

标签: c++ c


【解决方案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);

代码 sn-p 的输出将如下所示

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];
        }
    }

【讨论】:

    【解决方案2】:

    您正在对 字符串文字 进行操作,它是只读内存。当您尝试修改字符时,您会收到错误消息。

    将你的字符串数据复制到可写内存中,然后你就可以修改它了。

    最简单的改变是做这行:

    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;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-08
      • 2021-02-07
      • 1970-01-01
      • 2020-03-05
      • 1970-01-01
      • 2021-07-08
      • 1970-01-01
      • 2013-05-15
      相关资源
      最近更新 更多