2016-09-15 29 views
1

我給出一個字符串作爲這樣的:使用的memmove到字符串複製到自身產生錯誤的輸出

"Hello  World" 

有了5個空格字符插圖中的兩個詞。我想刪除這兩個詞之間的所有空格。但是,我的代碼似乎只有3個或更少的空間時纔有效。我正在使用memmove嘗試完成此操作。

這裏是我試過:

int main(void) { 
    char * word = malloc(sizeof(char)*16); 

    strcpy(word,"Hello  World"); 
    checkWords(word); 

    return 0; 
} 

void checkWords(char * word) { 
    int i; 
    for(i=0; i < strlen(word); i++) { 
     if(word[i] == ' ') 
      memmove(&word[i],&word[i+1],strlen(word)+1); 
    } 

    printf("The string without spaces is %s\n",word); 
} 

這裏的輸出爲"Hello World""Hello World"

如果嘗試輸入如:

"Hello World" gets me "Hello World" -->correct 

"Hello World" gets me "Hello World" -->correct 

什麼比3米更大的空間,得到我不正確的輸出。 。(我想有兩個詞之間有一個空格

+0

警告,使用'memmove',你必須處理'\ 0'字符。 – purplepsycho

+0

我已更新我的代碼以使用memmove,問題仍然存在。有任何想法嗎? – rerere

+0

試試這個if(word [i] ==''&& word [i + 1] =='')memmove(&word [i],&word [i + 1],strlen(word)+1);我 - ; }' – Karthick

回答

1

可能多次複製字符串的「右側」效率不高。使用strcpy()memcpy()不是一種有效的方法。

反覆調用strlen()也效率低下。

建議使用兩個索引並通過字符串走過它們。

#include <stdbool.h> 

void RemoveExtraSpaces(char * word) { 
    if (word[0]) { 
    size_t src = 1; 
    size_t dest = 1; 
    do { 
     if (word[src] != ' ' || word[src - 1] != ' ') { 
     word[dest] = word[src]; 
     dest++; 
     } 
    } while (word[src++]); 
    } 
    printf("The string without spaces is `%s`\n", word); 
} 

不清楚在第一個單詞之前或最後一個單詞之後有多個空格會發生什麼情況。這段代碼將這些縮小到1個空間。


接受變化 - 輕微的簡化。靈感來自@Joachim Pileborg很好的答案。

void RemoveExtraSpaces2(char * word) { 
    size_t src = 0; 
    size_t dest = 0; 
    do { 
    if (word[src] == ' ' && word[src + 1] == ' ') { 
     src++; 
    } 
    word[dest] = word[src]; 
    dest++; 
    } while (word[src++]); 

    printf("The string without spaces is `%s`\n", word); 
} 

因爲這是太接近是的Replace multiple spaces by single space in C重複,(順便說一句:這沒有接受最好的答案IMO),我提出這個社區的wiki。

1

這對我的作品

for(i=0; i < strlen(word); i++) { 
    if(word[i] == ' ') 
    { 
     while (word[i+1] == ' ' && word[i+1] != '\0') 
      memmove(&word[i],&word[i+1], strlen(word)-i); 
    } 
} 
+0

需要一段時間才能到達所有空間 – Alexi

+1

可以工作,但效率不高。 'O(N * N)'。然而,OP不在尋找效率。 – chux

+1

效率低下,更好的方法是找到第一個「非空間」位置,只做__one__'memmove'。 –

2

有四個方面的問題之一是未定義的行爲:以1,000,000字節串,即只有最後一個字符是一個空格。你將字符串的結束後移動約一兆一個字節着這是相當致命的

一種是隻是一個錯誤:您檢查字符串中的每個字符位置只有一次。如果你有兩個連續的。空間,你將第二個空間移動到第一個空間的位置在那裏。

還有一個是性能問題:如果您修復了前兩個問題,然後您只需要一個由空格組成的1,000,000字節的字符串,則您將執行100萬個移動,每個移動在0到1兆字節之間移動。這是500千兆字節的移動。這需要時間。

另一個性能問題是在循環中調用strlen。如果您的字符串是一百萬字節,那麼您會對strlen執行一百萬次調用,並且每次調用都會遍歷整個字符串直到結束,掃描尾隨零字節的整個兆字節字符串。

PS。我錯誤地解釋了你想要達到的目標:你的代碼將刪除任何單個空間,並從任意空間對中刪除一個空間。所以它爲你的每兩個空間留下一個空間。所以如果有一個空間,它將不會工作。它巧妙地適用於兩三個空間。如果你有很多空間,它將保留大約一半的空間。

+0

很好的解釋 - 除了我不認爲第一段適用。 'while(word [i + 1] ==''...'在你的1,000,000字節的情況下永遠不會是真的。 – chux

相關問題