2016-12-13 80 views
-1

我正在讀取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; 
} 

但是本程序是生成段故障。此代碼中的問題在哪裏?任何想法如何解決它?任何其他簡單的實現呢?

+2

@tinga您不能更改字符串文字。還有標準函數strstr,這將有助於快速找到字符串「//」 –

+3

這是一個奇怪的例子,採用一個有效的URI並將其變爲無效的URI。 – paddy

+0

可能的重複[爲什麼這個字符串反轉C代碼導致分段錯誤?](http://stackoverflow.com/questions/1614723/why-is-this-string-reversal-c-code-causing-a-segmentation -故障) – John3136

回答

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