>第 24 章 函数接口>可变参数>习题

cleansky cleanskyjojo@163.com
2009-11-05 16:27:33

请宋老师指正

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

char * int2ascii(int a)
{
	char * str;
	unsigned char r; //residual
	unsigned int  q;//quotient
	unsigned char i;

	if((a > 0x7FFFFFFF) || (a < (-2147483647-1))) return(NULL);	//this function only support 32bit-wide integer.  The range of signed int is (-2147483648, 2147483647)
	
	str = malloc(12);	//if assume integer type is 32bit width,  maximum 11 characters needed to store this integer.
	if(str == NULL)
	{
		puts("No available memory\n");
		return(NULL);
	}	

	for(i=0;i<11;i++) str[i]= ' ';// initialize all characters except the last one with blank. 		
	str[11]= '\0';	//use "end of string" to initialize the last one of the string.

	i=10;	//start from LSB 
	r=0;
	if(a >=0) 
		q=a;
	else
	{
		q=-a;	//nagative number

	}
	while(q >= 10)
	{
		r = q % 10;
		q /=10;
		str[i] = r + 0x30;	//convert integer to ascii character
		i--;
		if(i == 0) break; //out of range of char array. 	
		
	}
	str[i] = q + 0x30;	//convert MSB of this integer to ascii character
	i--;
	if(a < 0) str[i]='-';

	return(str);

}

void print_lu(const char * format, ...)
{
	va_list ap;
	char c;
	int dec;
	char *str;
	
	
	va_start(ap,format);
	while(c = *format ++)
	{
		if(c == '%')
		{
			c= *format++;
			switch(c)
			{
				case 'd' :
					{
						dec=va_arg(ap, int);		
						str=int2ascii(dec); // convert int to ascii characters
						fputs(str, stdout);
						free(str);	//free the memory allocated in int2ascii()/
						str=NULL;
						break;
					}
				
				case 's' :
					{
						str=va_arg(ap, char *);	
						fputs(str, stdout);
						break;
					}	
				default:
					break;
			}
		}
		else
		{
			putchar(c);
		}
	}

	va_end(ap);

}

int main(void)
{
	char * str;
	int d ;

	str ="test1 nagative number";
	d = -2147483647-1;
	print_lu("String = %s\nDecimal= %d\n\n",str,d);

	
	str ="test2\tnagative number";
	d = -2147483647;
	print_lu("String = %s\nDecimal= %d\n\n",str,d);

	str ="test3\t\\nagative number";
	d = -1234567;
	print_lu("String = %s\nDecimal= %d\n\n",str,d);
	

	str ="test4?**  zero";
	d = 0;
	print_lu("String = %s\nDecimal= %d\n\n",str,d);

	str ="test5 positive number";
	d = 12437;
	print_lu("String = %s\nDecimal= %d\n\n",str,d);

	str ="test6...:  positive number";
	d = 2147483647;
	print_lu("String = %s\nDecimal= %d\n\n",str,d);

	return 0;
}


cleansky cleanskyjojo@163.com
2009-11-05 16:29:20

//请宋老师指正
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>

char * int2ascii(int a)
{
	char * str;
	unsigned char r; //residual
	unsigned int  q;//quotient
	unsigned char i;

	if((a > 0x7FFFFFFF) || (a < (-2147483647-1))) return(NULL);	//this function only support 32bit-wide integer.  The range of signed int is (-2147483648, 2147483647)
	
	str = malloc(12);	//if assume integer type is 32bit width,  maximum 11 characters needed to store this integer.
	if(str == NULL)
	{
		puts("No available memory\n");
		return(NULL);
	}	

	for(i=0;i<11;i++) str[i]= ' ';// initialize all characters except the last one with blank. 		
	str[11]= '\0';	//use "end of string" to initialize the last one of the string.

	i=10;	//start from LSB 
	r=0;
	if(a >=0) 
		q=a;
	else
	{
		q=-a;	//nagative number

	}
	while(q >= 10)
	{
		r = q % 10;
		q /=10;
		str[i] = r + 0x30;	//convert integer to ascii character
		i--;
		if(i == 0) break; //out of range of char array. 	
		
	}
	str[i] = q + 0x30;	//convert MSB of this integer to ascii character
	i--;
	if(a < 0) str[i]='-';

	return(str);

}

void print_lu(const char * format, ...)
{
	va_list ap;
	char c;
	int dec;
	char *str;
	
	
	va_start(ap,format);
	while(c = *format ++)
	{
		if(c == '%')
		{
			c= *format++;
			switch(c)
			{
				case 'd' :
					{
						dec=va_arg(ap, int);		
						str=int2ascii(dec); // convert int to ascii characters
						fputs(str, stdout);
						free(str);	//free the memory allocated in int2ascii()/
						str=NULL;
						break;
					}
				
				case 's' :
					{
						str=va_arg(ap, char *);	
						fputs(str, stdout);
						break;
					}	
				default:
					break;
			}
		}
		else
		{
			putchar(c);
		}
	}

	va_end(ap);

}

int main(void)
{
	char * str;
	int d ;

	str ="test1 nagative number";
	d = -2147483647-1;
	print_lu("String = %s\nDecimal= %d\n\n",str,d);

	
	str ="test2\tnagative number";
	d = -2147483647;
	print_lu("String = %s\nDecimal= %d\n\n",str,d);

	str ="test3\t\\nagative number";
	d = -1234567;
	print_lu("String = %s\nDecimal= %d\n\n",str,d);
	

	str ="test4?**  zero";
	d = 0;
	print_lu("String = %s\nDecimal= %d\n\n",str,d);

	str ="test5 positive number";
	d = 12437;
	print_lu("String = %s\nDecimal= %d\n\n",str,d);

	str ="test6...:  positive number";
	d = 2147483647;
	print_lu("String = %s\nDecimal= %d\n\n",str,d);

	return 0;
}


吴书杰 wsj3000@gmail.com
2010-03-29 00:37:02

%f的怎么显示,不会,%d的很好写,我的代码,测试通过的额~~~:
#define SYNTAX_ERROR 0x1U

int printf(char * format, ...)
{
	int count;
	int i = 0;
	va_list ap;
	va_start(ap, format);

	while(format[i] != '\0'){
		if(format[i++] == '%'){
			switch(format[i++]){
			case 'd':
				put_d(va_arg(ap, int));
				break;
			case '%':
				putchar('%');
				break;
			default:
				exit(SYNTAX_ERROR);
			}
		}else{
			putchar(format[i-1]);
		}
	}

	va_end(ap);
	return count;
}

void put_d(int num)
{
	int num_tmp = num;

	while(num!=0){
		putchar('0' + num-(num_tmp=num_tmp/10)*10);
		num = num_tmp;
	}

	return;
}


吴书杰 wsj3000@gmail.com
2010-03-29 00:55:36

不好意思上个函数忘了统计打印字符个数:
#define SYNTAX_ERROR 0x1U

int printf(char * format, ...)
{
	int count = 0;
	int  j;
	va_list ap;
	va_start(ap, format);

	while(*format != '\0'){
		if(*format++ == '%'){
			switch(*format++){
			case 'd':
				count += put_d(va_arg(ap, int));
				break;
			case '%':
				putchar('%');
				break;
			default:
				exit(SYNTAX_ERROR);
			}
		}else{
			putchar(*(format-1));
			count++;
		}
	}

	va_end(ap);
	return count;
}

int put_d(int num)
{
	int num_tmp = num;
	int i = 0;
	while(num!=0){
		putchar('0' + num-(num_tmp=num_tmp/10)*10);
		num = num_tmp;
		i++;
	}

	return i;
}


cumirror tongjinam@qq.com
2011-10-02 15:17:11

对于_Bnd(X, bnd)可以再讲解下,我刚看这不理解其含义,后来参考了下面这篇文章:
http://learn.akae.cn/media/ch24s06.html


如果您有建设性意见,哪怕只是纠正一个错别字,也请不吝赐教,您留下的姓名和email将会出现在本书前言的致谢中。再次感谢您的宝贵意见!