C和指针 第九章 习题

9.15 编写函数格式化金钱为标准字符串

#include <stdio.h>
#include <string.h>
#define TEMP_LEN 1000

void dollars(char *dest, char const * src)
{
	
	int len;	
	int num;
	//当长度大于二,第一个逗号之前的字数
	int headerLen;
	//当前复制的位置
	int loc;
	len = strlen(src);
	char *dstTmp = dest;

	if (len <= 2) {
		//长度小于二,所有的都是五位,且前三位为 "$0.", 从第五位'\0'开始向前复制
		loc = 5;
		strcpy(dest, "$0.");
		//开始复制,还没有到复制结束点,即小数点前时
		while (loc >= 3) {
			//如果还有值需要复制,则继续复制
			if (len >= 0) {
				dest[loc] = src[len];
				len--;
			}else{
			//如果没有值复制,则补零
				dest[loc] = '0';
			}
			//向前位移一位
			loc--;
		}
	}else{
		/*长度大于二,最后两位可以先不管,将剩下的长度,与三 mod 操作,余数是开始的逗号前面的数字个数。
		  例如123456, (6 - 2) % 3 = 1,则第一个逗号前有1个数字,余数为零不加逗号*/
		*(dstTmp++) = '$';
		//当前正在复制的字符的坐标,和头部字符个数 0 1 2对应 3位 1位 2位
		loc = 0;
		headerLen = (len - 2) % 3;
		//开始从头往后复制字符
		while (loc < len - 2) {
			//当前位置为headerLen余数 + 3时,且src长度大于5时,此位置放置逗号,第一位不放逗号
			if (len > 5 && (loc % 3) == headerLen && loc > 0) {
				*dstTmp++ = ',';
				*dstTmp = src[loc++];
			}else {
				//其他情况均复制字符,loc移动一位
				*dstTmp = src[loc];
				loc++;
			}
			dstTmp++;
		}
		//尾数处理,加小数点,然后把最后两个数加上,然后加一个'\0'尾.
		*dstTmp++ = '.';
		*dstTmp++ = src[loc++];
		*dstTmp++ = src[loc];
		*dstTmp = '\0';
	}
}

int main()
{
	char src1[] = "";
	char src2[] = "1";
	char src3[] = "12";
	char src4[] = "123";
	char src5[] = "1234";
	char src6[] = "12345";
	char src7[] = "123456";
	char src8[] = "1234567";
	char src9[] = "123456789";
	char dest[100];

	dollars(dest, src1);
	printf("%s\n", dest);

	dollars(dest, src2);
	printf("%s\n", dest);

	dollars(dest, src3);
	printf("%s\n", dest);

	dollars(dest, src4);
	printf("%s\n", dest);

	dollars(dest, src5);
	printf("%s\n", dest);

	dollars(dest, src6);
	printf("%s\n", dest);

	dollars(dest, src7);
	printf("%s\n", dest);

	dollars(dest, src8);
	printf("%s\n", dest);

	dollars(dest, src9);
	printf("%s\n", dest);

	while (1)
		;
	return 0;
}

  运行:

9.16 指定格式格式化数字字符串

#include <string.h>
#include <stdio.h>
#define FALSE 0
#define TRUE  1

int format(char *format_string, char const *digit_string)
{
	int format_len    = strlen(format_string);
	int digit_len     = strlen(digit_string);

	//不符合要求数字字符串
	if (digit_len > format_len || digit_len == 0) {
		return FALSE;
	}
	//小数点位置指针,以及格式化字符和数字字符串末尾位置指针。
	char *point_ptr   = strchr(format_string, '.');
	char *format_ptr = format_string + format_len;
	char *digit_ptr  = digit_string + digit_len;

	//是否需要补零,如果小数点位置相对于数字结束位置左边则需要补零
	int need_zero = FALSE;
	if (point_ptr != NULL && point_ptr < (format_string + format_len - digit_len )) {
		need_zero = TRUE;
	}

	//最后一位是'\0'
	format_ptr--;
	digit_ptr--;
	while (format_ptr >= format_string) {
		//如果还有数字需要复制
		if (digit_ptr >= digit_string) {
			//正常情况直接复制
			if (*format_ptr == '#') {
				*format_ptr = *digit_ptr;
				digit_ptr--;
			}else if(*format_ptr == '.' || *format_ptr == ','){
			//遇到小数点,跳过小数点复制
				format_ptr--;
				*format_ptr = *digit_ptr;
				digit_ptr--;
			}
		}else{
			//数字字符复制完后,如果需要补零,则补零,否则补空
			if (need_zero == TRUE && format_ptr >= point_ptr) {
				//到达小数点位置,后面的就不需要补零
				if (format_ptr == point_ptr) {
					format_ptr--;
					need_zero = FALSE;
				}
				*format_ptr = '0';
			}else{
				//多余位补 _
				*format_ptr = '_';
			}
		}
		format_ptr--;
	}
}

int main()
{
	char format_str1[] = "###,###.###";
	char digit1[] = "1";
	format(format_str1, digit1);
	printf("%s\n", format_str1);

	char format_str2[] = "###,###,###";
	char digit2[] = "12345";
	format(format_str2, digit2);
	printf("%s\n", format_str2);

	char format_str3[] = "###,###.###";
	char digit3[] = "123";
	format(format_str3, digit3);
	printf("%s\n", format_str3);

	char format_str4[] = "###,###.###";
	char digit4[] = "1234";
	format(format_str4, digit4);
	printf("%s\n", format_str4);

	while (1)
		;
	return 0;
}

  执行结果:

 

posted @ 2016-08-31 01:30  xnuwu  阅读(342)  评论(0编辑  收藏  举报