2013-03-16 208 views
3

如何從字符串中刪除空格特殊字符?從字符串中刪除空格和特殊字符

我在Google上搜索時找不到一個答案。有很多與其他語言有關,但不是C.大多數人提到了使用正則表達式,這不是C標準(?)。

卸下易空間很簡單:

char str[50] = "Remove The Spaces!!"; 

然後用if語句的簡單循環:

if (str[i] != ' '); 

輸出將是:

RemoveTheSpaces!! 

我該怎麼加到if語句以便識別特殊字符並將其刪除?

我的特殊字符的定義:

Characters not included in this list: 
A-Z a-z 0-9 
+0

C中的字符串處理並不總是很有趣。把字符串看作只是一個「char」數組。你可以用'b'替換'a',但是沒有簡單的方法從數組中刪除字符索引,所以你最終還是會有一個漏洞。雖然,如果僅用於打印,您可以迭代數組,如果它不在a-zA-Z0-9的'ascii values'範圍內,則跳過任何操作並轉到下一個字符。在可能的情況下,這往往是最簡單的事情。否則,你需要複製到一個新的緩衝區。 – Jite 2013-03-16 01:40:32

回答

7

這是可能不是實現這一目標的最有效方式,但它可以相當快地完成工作。

注意:此代碼確實需要您包括<string.h><ctype.h>

char str[50] = "Remove The Spaces!!"; 
char strStripped[50]; 

int i = 0, c = 0; /*I'm assuming you're not using C99+*/ 
for(; i < strlen(str); i++) 
{ 
    if (isalnum(str[i])) 
    { 
     strStripped[c] = str[i]; 
     c++; 
    } 
} 
strStripped[c] = '\0'; 
+1

你忘了strStrippped的NUL終止:'''strStripped [c] ='\ 0';''在循環之後。 – 2013-03-16 01:41:19

+0

噢,是的,謝謝:) – 2013-03-16 01:41:49

+0

如果你假設C99之前,那麼'/ /'風格的評論也不支持。 – 2013-03-16 01:43:58

0

這是ASCII代碼範圍內

Char:Dec

0:48, 9:57 
A:65, Z:90 
a:97, z:122 

試試這個:

char str[50] = "Remove The Spaces!!"; 

int i =0; 
for(; i<strlen(str); i++) 
{ 
    if(str[i]>=48 && str[i]<=57 || str[i]>=65 && str[i]<=90 || str[i]>=97 && str[i]<=122) 
    //This is equivalent to 
    //if(str[i]>='0' && str[i]<='9' || str[i]>='A' && str[i]<='Z' || str[i]>='a' && str[i]<='z') 
     printf("alphaNumeric:%c\n", str[i]); 
    else 
    { 
     printf("special:%c\n", str[i]); 
     //remove that 
    } 
} 
0

使用您的if語句:

if (str[i] != ' '); 

隨着一點點的邏輯(字符必須是在範圍az或AZ或0-9:

If (!('a' <= str[i] && 'z' >= str[i]) && 
    !('A' <= str[i] && 'Z' >= str[i]) && 
    !('0' <= str[i] && '9' >= str[i])) then ignore character. 
+0

你知道你可以通過刪除'!'來簡化邏輯,只需用'||'替換'&&'。你已經否定了這個表達:) – Jite 2013-03-16 01:47:24

+0

這是真的大聲笑...我只是用一種很自然的方式寫它來理解它。出於某種原因,我喜歡並且比我更好......我可能只是很奇怪。 – 2013-03-16 02:15:50

1

這只是一個愚蠢的建議。

char ordinary[CHAR_MAX] = { 
    ['A']=1,['B']=1,['C']=1,['D']=1,['E']=1,['F']=1,['G']=1,['H']=1,['I']=1, 
    ['J']=1,['K']=1,['L']=1,['M']=1,['N']=1,['O']=1,['P']=1,['Q']=1,['R']=1, 
    ['S']=1,['T']=1,['U']=1,['V']=1,['W']=1,['X']=1,['Y']=1,['Z']=1, 

    ['a']=1,['b']=1,['c']=1,['d']=1,['e']=1,['f']=1,['g']=1,['h']=1,['i']=1, 
    ['j']=1,['k']=1,['l']=1,['m']=1,['n']=1,['o']=1,['p']=1,['q']=1,['r']=1, 
    ['s']=1,['t']=1,['u']=1,['v']=1,['w']=1,['x']=1,['y']=1,['z']=1, 

    ['0']=1,['1']=1,['2']=1,['3']=1,['4']=1,['5']=1,['6']=1,['7']=1,['8']=1, 
    ['9']=1, 
}; 

int is_special (int c) { 
    if (c < 0) return 1; 
    if (c >= CHAR_MAX) return 1; 
    return !ordinary[c]; 
} 

void remove_spaces_and_specials_in_place (char *str) { 
    if (str) { 
     char *p = str; 
     for (; *str; ++str) { 
      if (!is_special(*str)) *p++ = *str; 
     } 
     *p = '\0'; 
    } 
} 
+0

使用C99指定的初始值設定項。 – 2013-03-16 02:24:44

1

有數百萬種不同的方式可以完成。這裏只是一個不使用任何額外的存儲空間,並執行「就地」去除不需要的字符例如:

#include <stdlib.h> 
#include <stdio.h> 
#include <ctype.h> 

static void my_strip(char *data) 
{ 
    unsigned long i = 0; /* Scanning index */ 
    unsigned long x = 0; /* Write back index */ 
    char c; 

    /* 
    * Store every next character in `c` and make sure it is not '\0' 
    * because '\0' indicates the end of string, and we don't want 
    * to read past the end not to trigger undefined behavior. 
    * Then increment "scanning" index so that next time we read the 
    * next character. 
    */ 
    while ((c = data[i++]) != '\0') { 
     /* Check if character is either alphabetic or numeric. */ 
     if (isalnum(c)) { 
      /* 
      * OK, this is what we need. Write it back. 
      * Note that `x` will always be either the same as `i` 
      * or less. After writing, increment `x` so that next 
      * time we do not overwrite the previous result. 
      */ 
      data[x++] = c; 
     } 
     /* else — this is something we don't need — so we don't increment the 
      `x` while `i` is incremented. */ 
    } 
    /* After all is done, ensure we terminate the string with '\0'. */ 
    data[x] = '\0'; 
} 

int main() 
{ 
    /* This is array we will be operating on. */ 
    char data[512]; 

    /* Ask your customer for a string. */ 
    printf("Please enter a string: "); 

    if (fgets(data, sizeof(data), stdin) == NULL) { 
     /* Something unexpected happened. */ 
     return EXIT_FAILURE; 
    } 

    /* Show the customer what we read (just in case :-)) */ 
    printf("You have entered: %s", data); 

    /* 
    * Call the magic function that removes everything and leaves 
    * only alphabetic and numberic characters. 
    */ 
    my_strip(data); 

    /* 
    * Print the end result. Note that newline (\n) is there 
    * when we read the string 
    */ 
    printf("Stripped string: %s\n", data); 

    /* Our job is done! */ 
    return EXIT_SUCCESS; 
} 

我投入了大量的意見在裏面,所以希望該代碼不需要解釋。希望能幫助到你。祝你好運!

0
#include <stdio.h> 
#include <string.h> 

main() 
{ 
    int i=0, j=0; 
    char c; 
    char buff[255] = "Remove The Spaces!!"; 

    for(; c=buff[i]=buff[j]; j++){ 
     if(c>='A' && c<='Z' || c>='a' && c<='z' || c>='0' && c<='9'){ 
      i++; 
     } 
    } 

    printf("char buff[255] = \"%s\"\n", buff); 
} 
+0

只是一個建議......通過向代碼添加註釋並可能顯示輸出,可以改進此答案。 – 2014-05-19 18:57:52

+0

現在我看到,如果行中有多個特殊字符,代碼會將它們留在結果字符串中,並始終是該序列中每對兩個中的第二個。由於指令「buff [i] = buff [++ j];」那裏有一個錯誤,因爲它不假定在兩行或更多行中可能有特殊字符。而且變量「i」只有在源的「j」索引中的字符有效時才應增加,而不是一直增加。 – 2014-05-19 19:17:07

+0

所以要更正代碼: 1 - 取出else中的指令,即只讓「if」; 2 - 在每次迭代結束時(僅限「j」),不要增加「i」。 3 - 在指令「buff [i] = buff [j];」之後增加「if」中的「i」;或者用「buff [i ++] = buff [j];」替換這個intruction。 結果將會是一個代碼,與我編寫Jonathan Leffler編寫的代碼時編寫的代碼很相似,只不過在那一箇中​​,我忘了在「if」的條件中包含源字符串終止符以便複製終止符作爲結果字符串的有效字符。 – 2014-05-19 19:22:14

相關問題