C程序删除字符串中所有不必要的空格

标签 c arrays pointers char

我尝试创建一个 C 函数来删除字符串中所有不必要的空格。举个例子:

    Hi       my      name is  Leon   .

函数调用后,应该如下所示: Hi my name is Leon. 但我的程序总是在最后一个单词后面留一个空格,所以它看起来像这样:

Hi my name is Leon .

有什么办法可以解决这个问题吗? 代码如下:

char *DeleteSpaces(char *str) {
int blank = 1;
char *poc, *start = str, *q;
q = str;
while (*q == ' ') q++;
    poc = str;
    while (*poc++ = *q++);
while (*str != '\0') {
    q = str;
    if (*str == ' ') {
        if ((blank >= 1 && *(str-1) == ' ')) {
            poc = str;
            while (*poc == ' ') {
                poc++;
            }
            q = str;
            while(*poc != '\0') {
                *q++ = *poc++;
            }
            *q = '\0';
            blank = 0;

        }
        blank++;
    }
    else if (blank == 1)
        blank = 0;
    str++;
}
str--;
if (str == ' ') *str = '\0';

return start;
}

最佳答案

从字符串中删除空格时需要考虑许多微妙的问题。一个重要的问题是保留指向原始数据开头的指针,因此如果原始数据动态分配,您不会失去释放的能力稍后再调用内存,从而导致内存泄漏。

其次,重建索引需要考虑三个基本因素:(1) 前导空格; (2) 交错的空白; (3) 结尾后有空格。 (加上您想要构建的任何自定义情况,例如修剪 '.' 之前的任何空格)。您几乎可以在日常生活中按顺序执行它们。

虽然您现在只是查看' '(空格)字符,但您没有理由不处理所有空白 相同。 ctype.h header 提供了 isspace 函数(宏)来执行此操作。

将这些部分放在一起,您可以对 rmxws 执行类似以下操作(删除多余的空格):

char *rmxws (char *s)
{
    if (!s) return NULL;             /* valdiate string not NULL */
    if (!*s) return s;                    /* handle empty string */

    char *p = s, *wp = s;            /* pointer and write-pointer */

    while (*p) {
        if (isspace(*p)) {                         /* test for ws */
            if (wp > s)               /* ignore leading ws, while */
                *wp++ = *p;         /* preserving 1 between words */
            while (*p && isspace (*p))         /* skip remainder  */
                p++;
            if (!*p)                     /* bail on end-of-string */
                break;
        }
        if (*p == '.')       /* handle space between word and '.' */
            while (wp > s && isspace (*(wp - 1)))
                wp--;
        *wp++ = *p;                            /* use non-ws char */
        p++;
    }
    while (wp > s && isspace (*(wp - 1)))     /* trim trailing ws */
        wp--;
    *wp = 0;    /* nul-terminate */

    return s;
}

将其与一个简短的示例结合起来,您可以进行如下测试:

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

char *rmxws (char *s);

int main (int argc, char **argv) {

    char *s = argc > 1 ? argv[1] : (char []){ " Testing  1 2  3. . .  "};
    printf ("\n original : '%s'\n", s);
    printf (" trimmed  : '%s'\n\n", rmxws (s));

    return 0;
}

char *rmxws (char *s)
{
    if (!s) return NULL;             /* valdiate string not NULL */
    if (!*s) return s;                    /* handle empty string */

    char *p = s, *wp = s;            /* pointer and write-pointer */

    while (*p) {
        if (isspace(*p)) {                         /* test for ws */
            if (wp > s)               /* ignore leading ws, while */
                *wp++ = *p;         /* preserving 1 between words */
            while (*p && isspace (*p))         /* skip remainder  */
                p++;
            if (!*p)                     /* bail on end-of-string */
                break;
        }
        if (*p == '.')       /* handle space between word and '.' */
            while (wp > s && isspace (*(wp - 1)))
                wp--;
        *wp++ = *p;                            /* use non-ws char */
        p++;
    }
    while (wp > s && isspace (*(wp - 1)))     /* trim trailing ws */
        wp--;
    *wp = 0;    /* nul-terminate */

    return s;
}

示例使用/输出

$ ./bin/trimxsws "    Hi       my      name is  Leon   .  "

 original : '    Hi       my      name is  Leon   .  '
 trimmed  : 'Hi my name is Leon.'

或者只是

$ ./bin/trimxsws

 original : ' Testing  1 2  3. . .  '
 trimmed  : 'Testing 1 2 3...'

仔细检查一下,如果您还有任何其他问题,请告诉我。

关于C程序删除字符串中所有不必要的空格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38956890/

相关文章:

pointers - 隐藏 nil 值,理解为什么 golang 在这里失败

c++ - OpenCV cv::Mat to short*(避免 memcpy)

java - 在java中不使用for循环填充一维数组

C代码函数调用不起作用

c - 将 Char 值增加一

C程序链表添加到末尾

javascript - 为什么我的代码不能运行?插入排序

c - char *a[]= {"hello", "world"}; 之间有什么区别?和 char a[][10]= {"hello", "world"};?

c++ - 如何提高轮廓精度?

c - 结构数组 : Structure members are Enum Variables