C程序设计语言(第2版)----课后练习题1-21

练习1-21 编写程序entab,将空格串替换为最少数量的制表符和空格,但要保持单词之间的间隔不变。
本程序远远超出了题目要求,我不仅考虑了空格串,还考虑了制表符串以及空格制表符混合串。

//本程序远远超出了题目要求,我不仅考虑了空格串,还考虑了制表符串以及空格制表符混合串。
#include<stdio.h>
#define MAXLEN 1000
#define TABNUM 8

int getline(char s[], int maxlen);
void entab(char s[],int maxlen);
int countminblank(char s[]);

int main()
{
	int len;
	char line[1000];
	while ((len = getline(line, MAXLEN)) > 0) {
		entab(line,MAXLEN);
	}
	return 0;
}

//将输入句子储存至字符数组中,并统计句子长度,len=0时说明句子只有EOF;
int getline(char s[], int maxlen) {
	int i;
	char c;
	for (i = 0; (c = getchar()) != EOF && c != '\n' && i < maxlen - 1;i++)
		s[i] = c;
	if (c == '\n')
		s[i++] = c;
	s[i] = '\0';
	return i;
}

//将输入句子中的每个单词以最小间隔隔开,并形成新的句子
void entab(char s[],int maxlen) {
	int i,j,m,n,r,k=0;//i:源字符组的索引下标,j:目标字符组的索引下标,r:源字符组中当前空格串或者制表符串或者空格与制表符串的长度,k:目标字符组的当前光标位置
	int tabnum, blanknum;
	char to[MAXLEN];
	int intervel;
	intervel = countminblank(s);//得到输入句子中单词之间的最小间隔
	for (i = 0,j=0; s[i] != '\0';) {
		if (s[i] == '\t' || s[i] == '\40') {
			//在单词之间插入制表符以及空格以满足最小间隔要求
			tabnum =(k+intervel - 1) / TABNUM- k / TABNUM;//计算需要插入的制表符
			for (m = 0,n=0; m < tabnum; m++) {
				to[j++] = '\t';
				n+= (TABNUM - k%TABNUM);
			}
			blanknum =intervel - n;//计算需要插入的空格符
			for (m = 0; m < blanknum; m++)
				to[j++] = '\40';
			k += intervel;//更新插入制表符和空格符后的目标句子的光标位置
			//得到源字符串中当前空格串或者制表符串或者空格和制表符串的长度,并更新源字符串中的索引下标
			r = 0;
			while (s[i+r] == '\t' || s[i+r] == '\40')
				r++;
			i += r;
		}
		//打印单词到目标字符串中
		else {
			to[j++] = s[i];
			k++;
			i++;
		}
	}
	to[j] = '\0';
	printf("%s", to);
}

//统计输入句子中单词之间的最小间隔
int countminblank(char s[]){
	int blanknum=0;
	int minblanknum=0;
	int i=0,j=0,m=0;
	for (i = 0; s[i] != '\0';) {
		if (s[i] == '\t' || s[i] == '\40') {
			//得到每个空格串或者制表符串或者空格制表符串的等效空格长度blanknum
			for (j = 0; s[i+j] == '\t' || s[i+j] == '\40';j++) {
				if (s[i + j] == '\t') {
					blanknum += (TABNUM - (m%TABNUM));
					m += (TABNUM - (m%TABNUM));
				}
				else {
					blanknum += 1;
					m++;
				}
			}
			i += j;
			//得到所有空格串或者制表符串或者空格制表符串的最小等效空格长度minblanknum;
			if (minblanknum == 0)
				minblanknum = blanknum;
			if (blanknum < minblanknum)
				minblanknum = blanknum;
			blanknum = 0;
		}
		else { 
			i++;
			m++;
		}
	}
	return minblanknum;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值