读经典之TCPL练习三


版本1:

/*
	date:9-2-2014
	author:doodlesomethig
	fuction:
	change day to month
	change month to day
	this is the pointer version
*/



#include <stdio.h>


int main() {
	int year,month,day,yearday;
	int dayofyear(int year,int month,int day);
	int monthofyear(int year,int total_day,int *month,int *day);
	char *month_name(int n);
	printf("%d\n",dayofyear(2014,9,2));
	monthofyear(2014,246,&month,&day);
	printf("%d(%s),%d\n",month,month_name(month),day);
	return 0;
}
	static int daytabs[2][13] = {
			{0,31,29,31,30,31,30,31,31,30,31,30,31}, //leap year
			{0,31,28,31,30,31,30,31,31,30,31,30,31} //it's not a leap year
			};

	int dayofyear(int year,int month,int day) {

		int leap;
		int days;
		int *p;
		int *tmp;

		days=0;

		//the value of leap is 1(true) or 0(false)
		leap =  year%4 == 0 && year%100 != 0 || year%400 == 0;

		if(year < 1949 || month > 12 || month < 1 || day < 1)
			return -1;

		p = &daytabs[leap][0];
		tmp=p;

		if(day > *(tmp + month))
			return -1;

		for(;tmp< (p + month);tmp++)
			days += *tmp;
	
		days += day;

		return days;

	}

	int monthofyear(int year,int total_day,int *month,int *day) {

		int leap;
		int *p;
		int i;
		
		i=1;
		leap =  year%4 == 0 && year%100 != 0 || year%400 == 0;
		
		if(year < 1949 || total_day<1)
			return -1;
		
		if( (leap && total_day>365) || (!leap && total_day>366) )
			return -1;

		p = &daytabs[leap][1];

		for(;*p < total_day;p++) {
			total_day -= *p;
			i++;
		}

		*month=i;
		*day = total_day;

		return 0;
	}
	//the function will return the pointer of the month of sting
	char *month_name(int n) {
		static char *name[]={"January","February","March",
		"April","May","June","July","August","September","October","November",
		"December"};
		return name[n-1];
	}



版本2:

/*
	date:9-3-2014
	author:doodlesomething
	version:1.0

	功能:使用指针实现dayofyear() 和monthofyear()
	即将一年中的第几天转换为年月日,其中月应包含英文别名

	question:本来是想用指针数组实现存储daytab却一直报错,无法解决。
*/

#include <stdio.h>


int main() {
	int year,month,day,yearday;
	int dayofyear(int year,int month,int day);
	int monthofyear(int year,int total_day,int *month,int *day);
	char *month_name(int n);

	printf("%d\n",dayofyear(2014,9,3));
	monthofyear(2014,247,&month,&day);
	printf("%d(%s),%d\n",month,month_name(month),day);

	return 0;
}
	
	//之所以加上0是因为方便以12为单位计算
	static int daytab[]={
		0,
		31,
		31+28,
		31+28+31,
		31+28+31+30,
		31+28+31+30+31,
		31+28+31+30+31+30,
		31+28+31+30+31+30+31,
		31+28+31+30+31+30+31+31,
		31+28+31+30+31+30+31+31+30,
		31+28+31+30+31+30+31+31+30+31,
		31+28+31+30+31+30+31+31+30+31+30,
		31+28+31+30+31+30+31+31+30+31+30+31,
		0,
		31,
		31+29,
		31+29+31,
		31+29+31+30,
		31+29+31+30+31,
		31+29+31+30+31+30,
		31+29+31+30+31+30+31,
		31+29+31+30+31+30+31+31,
		31+29+31+30+31+30+31+31+30,
		31+29+31+30+31+30+31+31+30+31,
		31+29+31+30+31+30+31+31+30+31+30,
		31+29+31+30+31+30+31+31+30+31+30+31
	};

	//判断是否为闰年  0-不是 1-是
	int leap(int year) {
		return ( ( (year%4 == 0) && year%100 != 0 ) || year % 400 == 0 );
	}

	int dayofyear(int year,int month,int day) {
		int leap(int year);
		//这一行挺有意思
		return *(daytab + month + !leap(year) * 12 ) + day;
	}

	int monthofyear(int year,int yearday,int *month,int *day) {
		int m,ly;

		ly = leap(year);
		//这一行比较有意思,注意ly取反 --简单的错误判断
		if(yearday < 1 || yearday>(355+!ly)) {
			return -1;
		}

		m = ly ? 11 : 23;

		//到达正确的数组位置
		while(yearday < *(daytab + m)) {
			m--;
		}
		//月
		if(month) {
			*month = m % 12 ;
		}
		//天数
		if(day) {
			*day =yearday - (*(daytab + m));
		}

		return 0;
	}
	
	//the function will return the pointer of the month of sting--别名
	char *month_name(int n) {

		static char *name[]={"January","February","March",
		"April","May","June","July","August","September","October","November",
		"December"};

		return name[n-1];
	}




    

      练习 5-13  编写程序 tail,将其输入中的最后 n 行打印出来。默认情况下,n 的值为10,但可通过一个可选参数改变 n 的值,因此,命令tail -n将打印其输入的最后 n 行。无论输入或 n 的值是否合理,该程序都应该能正常运行。编写的程序要充分地利用存储空间;输入行的存储方式应该同 5.6 节中排序程序的存储方式一样,而不采用固定长度的二维数组。


如果要写head,只需要简单就该即可


/*
	date:9-4-2014
	author:doodlesomething
	version:1.0

	tail -- linux tool

	how:
	1.read lines;
	2.write lines;
*/

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


#define MAXLINES 1000	//define the maxsize of input lines
#define MAXBUFPSIZE 50000 //define the maxsize of bufp

#define MAXLEN 1000 //the maxsize of evey line

char *lineptr[MAXLINES];  //to store the pointers of lines

int readlines(char *lineptr[],int lim);
void writelines(char *lineptr[],int nlines,int n);



//main function 
int main(int argc,char *argv[]) {
	int nlines;
	int n;
	
	n=3;

	//when the nlines bigger than 1 we sort the lines
	if( (nlines = readlines(lineptr,MAXLINES) ) >0) {
		//没输入参数时
		if(argc==1) 
			writelines(lineptr,nlines,n);
		else {
			if( (*++argv)[0] == '-') {
				n=atoi(++argv[0]);
				writelines(lineptr,nlines,n);
			}
			else {
				printf("Usage:tail -n\n");
			}
		}
	}
	else 
		printf("No input line to tail\n");
	

	return 0;
}

	//read line string
	int readlines(char *lineptr[],int lim)	{
		int len,inlines;
		char *p;
		char line[MAXLEN];
		int getLine(char *line,int lim);
		char *alloc(int n);
	
		inlines = 0;
		
		while( (len = getLine(line,MAXLEN)) > 0 ) {
			if( inlines > lim ||  ( p = alloc(len) ) == NULL ) 
				return -1;
			else {
				/*
				the end of input line is '\n',and we should store it
				as a string so we can should add a flag '\0' end of a string array
				*/
				line[len-1]='\0';  
				strcpy(p,line);
				lineptr[inlines++]=p;
			}
		}

		return inlines;
	}



	//write line string
	void writelines(char *lineptr[],int nlines,int n) {
		printf("\n");
		//如果所输入的参数大于总行数时
		if(n>nlines) 
			n=nlines;

		while( (n--) > 0) {
			printf("%s\n",  lineptr[nlines-1-n] );
		}
	}

	//get the single line
	int getLine(char *line,int lim) {
		int c;
		char *tmp;

		tmp = line;
		
		while(--lim > 0 && (c = getchar()) != EOF && c != '\n')
			*tmp++=c;
		/*
		在开始程序时,我的代码如下:
		if(c == '\n')
			*tmp=c;
		*++tmp='\0';
		这样无论怎样输入回车加上ctrl+d,tmp的值为1 
		函数的最后返回值都大于零,无法结束输入
		*/

		if(c == '\n')
			*tmp++= c;

		*tmp= '\0';



		//return the length of line
		return (int) (tmp-line);
	}
	
	//buf
	static char buf[MAXBUFPSIZE];
	static char *bufp = buf;

	//ask for buf
	char *alloc(int n) {
		if(n > 0 && (buf + MAXBUFPSIZE - bufp) >= n) {
			bufp = bufp + n;
			return (bufp - n);
		}
		else 
			return 0;
	}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值