从一个字符串中去除多余的空格。

      字符串中如果有一个地方由一个或多个连续的空格组成,就把它们改成单个空格字符。注意当遍历整个字符串时要确保它以NUL字符结尾。

      此处的空格的含义包括但不限于空格字符,为什么呢?空格、水平制表、垂直制表、换页、换行、回车在控制台输出的时候都会让我们感觉字符之间由空格隔开了,所以,在遍历字符串的时候,应该对上述特殊字符进行处理。只有这样,才更符合我们的习惯。

#include<stdio.h>
#include<assert.h>
#define NUL '\0'

int 
is_white(int ch)
{
	return ' ' == ch || '\t' == ch || '\v' == ch 
		|| '\f' == ch || '\n' == ch || '\r' == ch;
}

void
deblank(char *str) {
	assert(NULL != str);
	
	/*
	**将两个指针都指向字符串的首部。
	*/
	char *src = str;
	char *dest = str;
	
	/*
	**遍历整个字符数组
	*/
	for (; *src != NUL;) {
		
		/*
		**首次出现空格,进行复制,
		**紧接着再次出现,直接跳过。
		*/
		if (is_white(*src)) {
			*dest++ = ' ';
			src++;
			while (is_white(*src)) {
				src++;
			}
		}
		
		/*
		**如果不是空格的话,后面的值复制到前面去。
		*/
		else {
			*dest++ = *src++;
		}
	}
	
	/*
	**添加结束符 '\0'。
	*/
	*dest = NUL;
}

int main() {
	char str[] = "I\t\t\tlike      it   !";
	printf("删除多余的空格前:\n%s\n", str);
	deblank(str);
	printf("删除多余的空格后:\n%s\n", str);
	return 0;
}
      处于对程序健壮性的考虑,我在删除多余空格函数deblank函数体最前面加上了断言, 只有输入的指针参数非空进行后续操作才是合法的,不然会产生不可预料的后果。
本程序在VS2017下编译运行通过。

对程序进行分析,我们可以发现,判断是否首次是否为“空格”,出现了两重循环,我在第一次创作这篇博客的半个月后,突然想到了改进版本:

  • 新的版本只出现了一重循环
#include<stdio.h>
#include<assert.h>
#define NUL '\0'

int 
is_white(int ch)
{
	return ' ' == ch || '\t' == ch || '\v' == ch 
		|| '\f' == ch || '\n' == ch || '\r' == ch;
}

void
deblank(char* str) 
{
	assert(NULL != str);
	/*
	**将两个指针都指向字符串的首部。
	*/
	int tag = false;//判断是否为首次出现空格。
	char *src = str;
	char *dest = src;
	/*
	**遍历整个字符数组
	*/
	for (; *src != NUL;) {

		/*
		**首次出现空格,进行复制,
		**紧接着再次出现,直接跳过。
		*/
		if (is_white(*src))
		{
			*dest = ' ';
			if (tag) {
				dest++;
				tag = false;
			}
			src++;
		}
		else
		{
			tag = true;
			*dest++ = *src++;
		}
	}

	/*
	**添加结束符 '\0'。
	*/
	*dest = NUL;
}

int 
main() {
	char str[] = "I\t\t\tlike      it   !";
	printf("删除多余的空格前:\n%s\n", str);
	deblank(str);
	printf("删除多余的空格后:\n%s\n", str);
	return 0;
}

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值