版本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;
}