我尝试创建一个 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/