【问题标题】:How to remove spaces that are in a string sentence如何删除字符串句子中的空格
【发布时间】:2011-12-11 01:03:01
【问题描述】:

我正在尝试编写代码来删除句子的所有前导、尾随和中间空格,但在单词之间只保留一个空格。

例如,如果输入是

"    This    is my     string    "

输出应该是

"This is my string"

到目前为止,我想出了这个:

#include <stdio.h>
void cascade(char str[], int i);
main()
{
    char str[100] = "    This    is my     string    ";
    int i = 0;
    while (str[i] != '\0') {
            if (str[i] == ' ' && str[i + 1] == ' ')
                    cascade(str, i);
            i++;
    }
    printf("%s\n", str);
}

void cascade(char str[], int i)
{
    while(str[i] != '\0') {
            str[i] = str[i + 1];
            i++;
    }
    str[i + 1] = '\0';
}

如果有人能提出一些想法,我将不胜感激,谢谢。

【问题讨论】:

  • 你可以使用字符串函数吗?
  • 是的,我们可以使用 string.h 库。
  • 你如何定义“单词”?如果您的“单词”包含制表符、换行符或其他空白字符会怎样?
  • 请注意,您不仅要尝试将多个空格折叠成一个空格,还需要删除字符串开头和结尾的所有空格。这让事情有点复杂。
  • 这只是一个硬编码的变量,所以不会改变

标签: c


【解决方案1】:

使用两个指针。第一个指向要读取的下一个字符,第二个指向要写入的位置。

如果连续读取两个空格,请不要提前写入指针。


您可能要考虑的另一种方法是使用strtok" " 作为分隔符。

【讨论】:

  • 这是一个很好的答案,但这是一个homework 的问题。如果你给出完整的答案,那有什么意义呢?
  • 这是一个非常好的答案,但我认为 BLUEPIXY 使用相同的方法来写出代码。还是谢谢
【解决方案2】:
#include <stdio.h>
#include <string.h>

char* trim(char str[]){
    char *p=str;
    char *token;
    if(str == NULL) return NULL;
    if(*str == '\0') return str;

    token=strtok(str, " \t");
    if(token == NULL){
        *str = '\0';
        return str;
    }
    while(NULL!=token){
        int len;
        len = strlen(token);
        if(p != token){
            memmove(p, token, len);
        }
        p += len;
        *p++ =' ';
        token = strtok(NULL, " \t");
    }
    p[-1]='\0';

    return str;
}

int main(){
    char str[100] = "    This    is my     string    ";
    printf("\"%s\"\n", trim(str));
    return 0;
}

【讨论】:

  • 太棒了,就是这样。只是为了清楚起见,我稍微压缩了你的函数,以便每个 c 新手都更容易理解。谢谢
【解决方案3】:

你可以有两个数组和两个计数器。每次迭代你总是增加你的第一个计数器,但只有当角色不是空格时才会增加你的第二个。它的表格如下所示。

  Char   In-Pos  Out-Pos

   ' '      0      0
   ' '      1      0
   ' '      2      0
   ' '      3      0
   'T'      4      0
   'h'      5      1
   'i'      6      2
   's'      7      3
   ' '      8      4
   ' '      9      5
   ' '     10      5
   ' '     11      5
   'i'     12      5
   's'     13      6
   ' '     14      7
   'm'     15      8
   'y'     16      9
   ' '     17     10
   ' '     18     11
   ' '     19     11
   ' '     20     11
   ' '     21     11
   's'     22     11
   't'     23     12
   'r'     24     13
   'i'     25     14
   'n'     26     15
   'g'     27     16
   ' '     28     17
   ' '     29     18
   ' '     30     18
   ' '     31     18

【讨论】:

  • 我更改了表格以希望更清晰。这个想法是当它找到一个空间时,除了 In-Pos 之外,你不会改变任何东西。所以一开始,在你得到一个有效的字符之前,不会在输出中设置任何内容,例如,'T'。最后,我们从不设置最后的空格。
  • 更接近,但不要忘记 NUL 是最后一个字符,并且字符串末尾不应有空格。这是一个好主意,但“字符串的末尾或开头没有空格”使它更加复杂。
  • 这是一个非常有趣的解决方案,但我相信这对我来说不是入门级方法,因为我刚刚开始学习 c。但是非常感谢您抽出宝贵的时间
【解决方案4】:

您可以在第一个实例中使用字符串标记器,并使用空格(“”)作为分隔符。为此,您在 C 中使用 strtok。然后解析 strtok 函数的输出,并且对于每个元素,如果它包含更多空白字符,则消除它们。您还将每个更正的元素放在另一个数组中。 然后,您所要做的就是解析新数组并在每个元素后添加一个空格。如果您喜欢这个想法,我可以为您提供代码草稿。

【讨论】:

  • 感谢您的建议,我认为 BLUEPIXY 使用的是相同的方法,他也使用了 strtok 函数。谢谢
【解决方案5】:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

char** split(const char *str, const char *delimiter, size_t *len){
    char *text, *p, *first, **array;
    int c;
    char** ret;

    *len = 0;
    text=strdup(str);//strdup not standard
    if(text==NULL) return NULL;
    for(c=0,p=text;NULL!=(p=strtok(p, delimiter));p=NULL, c++)//count item
        if(c==0) first=p; //first token top

    ret=(char**)malloc(sizeof(char*)*c+1);//+1 for NULL
    if(ret==NULL){
        free(text);
        return NULL;
    }
    //memmove?
    strcpy(text, str+(first-text));//skip until top token
    array=ret;
    for(p=text;NULL!=(p=strtok(p, delimiter));p=NULL){
        *array++=p;
    }
    *array=NULL;
    *len=c;
    return ret;
}

void free4split(char** sa){
    char **array=sa;

    if(sa!=NULL){
        free(array[0]);//for text
        free(sa);      //for array
    }
}

int main(void){
    char str[100] = "    This    is my     string    ";
    char **words;
    size_t len=0;
    int i;

    words = split(str, " \t", &len);
    *str = '\0';
    for(i = 0;i<len-1;++i){
        strcat(str, words[i]);
        strcat(str, " ");
    }
    strcat(str, words[i]);
    printf("\"%s\"\n", str);
    free4split(words);
    return 0;
}

【讨论】:

  • 哇,非常感谢你所做的一切努力,它工作得很好,我认为你也在使用非常有用的 strtok 函数,而且你使用过的指针(如 BLUEPIXY)也帮助了它很多。但是如果没有这么复杂不是更好吗?但是它工作正常,这就是这种情况下的问题,谢谢
猜你喜欢
  • 1970-01-01
  • 2018-12-31
  • 1970-01-01
  • 2011-09-30
  • 2021-12-01
  • 2021-09-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多