现在的位置: 首页 > 综合 > 正文

C程序设计(第二版 新版)第五章 习题

2013年10月16日 ⁄ 综合 ⁄ 共 9703字 ⁄ 字号 评论关闭

1.getline(char *line, int limit) 输出的形式3种。(5.6中遇到)

/*
getline(char *line,int limit)函数的line结果有3种:
1. 字符串 + 换行符 + EOF 
2. 字符串 + EOF (在第一行输入字符串+EOF+换行,在下一行行首输入EOF即可) 
3.  EOF(在终端的行首输入ctrl+z)
*/ 
int getline(char *line, int limit)
{
	int c;
	char *ptr = line;
	while(--limit > 0 && (c = getchar())!= EOF && c != '\n')
		*ptr++ = c;
	if(c == '\n')
		*ptr++ = c;
	*ptr = '\0';
	return ptr - line;
}

2.编写expr,以计算命令行输入的逆波兰的值,其中每个运算符或操作数用一个单独的参数表示。例如命令   expr  2  3  4  +  *

本题有bug:单输入例子的  expr 2 3 4 + * 结果不对,原因是 *号是dos的通配符。

#include<stdio.h>
#include<stdlib.h> //atof
#include<ctype.h>   // isdigit

#define MAXLEN 1000

double stack[MAXLEN];
int sp = 0;

void push(double c)
{
	if(sp >= MAXLEN)
		printf("the stack is full\n");
	else
		stack[sp++] = c;	
}

double pop()
{
	if(sp <= 0)
		printf("the stack is empyt\n");
	else
		return stack[--sp];
}

int main(int argc, char * argv[])
{
	int i;
	int c;
	double op2;
	
	for(i=1; --argc > 0; ++i)
	{
		c = argv[i][0];
		if(isdigit(c))
			push(atof(argv[i]));
		else
		{
			switch(c)
			{
				case '+':
					push(pop()+pop());
					break;
				case '-':
					op2 = pop();
					push(pop()-op2);
					break;
				case '*':
					push(pop() * pop());
					break;
				case '/':
					op2 = pop();
					if(op2 != 0)
						push(pop() / op2);
					else
						puts("the division is zero\n");
					break;
				default:
					puts("error: the input is wrong");
					break;		
			}
		}			
	}
	printf("the result is %f\n",pop());
	
	return 0;
}

 3.编写detab和entab程序(5-11)

   detab :将输入的制表符替换为适当数目的空格,是空格充满到下一个制表符终止的地方 

   entab :将空格替换为最少量的制表符和空格

   下面的程序是是习题(5-11)的,对课后题的答案有所改动

   但是对于想(5-12)的形式  entab -m +n 这种表示制表位从m开始,每隔n列停止,表示不是很理解的是,对于m列前面的数来说,遇到'\t'怎么处理啊?难道也要等到m列之  

  后,很费解,都没有写这个程序,可以见课后题答案。

  这个程序重点的就是tab[]数组的应用,不管是怎样的变化,都是修改tab数组,这才是核心。

  两个程序共同的部分都是settab和tabpos,如下:

#include"head.h"

void settab(int argc, char *argv[], char *tab)
{
    int i, pos;
    
    if (argc <= 1)
    {
        for (i = 1; i <= MAXLINE; i++)
        {
            if (i % TABINC == 0)
                tab[i] = YES; 
            else
                tab[i] = NO;   
        }    
    }    
    else
    {
        for (i = 1; i <= MAXLINE; i++)
            tab[i] = NO; 
        while (--argc > 0)
        {
            pos = atoi(*++argv); 
            if (pos > 0 && pos <= MAXLINE) 
                tab[pos] = YES;  
        }   
    }
}
#include"head.h"

int tabpos(int pos, char *tab)
{
    if (pos > MAXLINE)
        return YES;
    else
        return tab[pos];    
}

对于entab:

Head.c

#include <stdio.h>

#define MAXLINE 100
#define TABINC 8
#define YES 1
#define NO 0

void settab(int argc, char *argv[], char *tab);
void entab(char *tab);
int tabpos(int pos, char *tab);

man.c

#include"head.h"

int main(int argc, char *argv[])
{
	freopen("Example.in","r",stdin);
	
    char tab[MAXLINE+1];
    printf("1231234123123451234\n"); //Êä³ö±ÈÕÕ¸÷¸öλÖÃÓÃµÄ 
    settab(argc, argv, tab);
    entab(tab);
    
    return 0;  
}

entab.c

#include"head.h"

void entab(char *tab)
{
    int c, pos;
    int nb = 0;
    int nt = 0;
    
    pos  = 1;
    while((c = getchar()) != EOF)
    {
        if (c == ' ') 
        {
            if (tabpos(pos, tab) == NO)
                nb++;
            else
            {
                nb = 0;
                nt++;
            }    
        }  
        else
        {
            for(;nt > 0;--nt)
            {
            	do
            	{
           			putchar(' ');  
	            }while(tabpos(pos++,tab)== NO);
				      	
            }
            if (c == '\t')
            {
            	nb = 0;
            	do
            	{
           			putchar(' ');  
	            }while(tabpos(pos++,tab) == NO);
            }  
            else
            {
                for(;nb > 0; --nb) putchar(' ');    
                if(c == '\n')
                	pos = 0;
               	putchar(c);
               	++pos;
            }    
        } 
    }    
}

 

对于detab:

Head.c

#include<stdio.h>

#define TABINC 8

#define YES 1
#define NO  0

#define MAXLEN 100

void settab(int argc, char * argv[], char *tab);
int tabpos(int pos, char *tab);
void detab(char *tab);

 

main.c

#include"Head.h"

int main(int argc, char* argv[])
{
	freopen("Example.in","r",stdin);
	
	char tab[MAXLEN + 1];
	settab(argc,argv,tab);
	detab(tab);
	
	return 0;	
}

 

detab.c

#include"Head.h"

void detab(char *tab)
{
	int c;
	int pos = 1;
	
	while((c = getchar()) != EOF)
	{
		if(c == '\t')
		{
			do
			{
				putchar(' ');
			}while(tabpos(pos++,tab) == NO);
		}
		else if( c == '\n')
		{
			putchar(c);
			pos = 1;
		}
		else
		{
			putchar(c);
			++pos;
		}
	}
}

 

4.tail -n 打印输入的最后n行。

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

#define  DEFLINES 10 // default  of lines to print
#define  LINES    100 // maxs of lines to print
#define  MAXLEN   100 // max length of an input line

int getline(char *line, int limit)
{
	int c;
	char *p = line;
	int pos = 0;
	while(--limit > 0 && (c = getchar()) != EOF && c != '\n')
		*p++ = c;
	if( c == '\n')
		*p++ = c;
	p[pos] = '\0';	
	return p - line;
}

char alloc[MAXLEN * LINES];
char *buf = alloc;
char *bufend = alloc + MAXLEN * LINES;
char* alloctor(int len) // 
{
	if( buf + len + 1 >= bufend)
		printf("the room is full\n");
	else
	{
		buf += len + 1;		
		return buf - len - 1;
	}
		
}

int main(int argc, char *argv[])
{
	freopen("Example.in","r",stdin);
	
	char line[MAXLEN];
	char *lineptr[MAXLEN];
	int n;
	int i;
	int nlines;
	int totallines; 
	int len;
	
	if(argc <= 1)
		n = DEFLINES;
	else if(argc == 2 && (*++argv)[0] == '-')
	{
		n = atoi(++argv[0]);
		if(n < 1 || n > LINES)
			n = DEFLINES;			
	}
	else
	{
		printf("usage: tail [-n]\n");
		exit(1);
	}
	
	for(i = 0; i < LINES; ++i)
		lineptr[i] = NULL;
	
	nlines = 0;

	while((len = getline(line,MAXLEN)) > 0)
	{
		lineptr[nlines] = alloctor(len);
		strcpy(lineptr[nlines],line);
		nlines ++;
	}
	if( n > nlines)
		n = nlines;
	
	int first = nlines - n;
	
	for(i = (first + LINES) % LINES; --n >= 0;i = (i + 1 + LINES) % LINES )
		printf("%s",lineptr[i]);
		
	return 0;
}

 5. 对文本行就行排序,核心函数qqsort(void * lineptr[], int left, int rifht, int (*comp)(void *, void *))

本程序的详解见:http://blog.csdn.net/chenyiming_1990/article/details/9403123

Head.h

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

#define MAXLEN 100  //max of one line
#define MAXLINE 5000 // max of lines
char *lineptr[MAXLINE];

int getline(char *line, int limit);
int readline(char *lineptr[], int lines);
void writeline(char *lineptr[], int nlines);
void qqsort(void *v[], int left, int right, int (*comp)(void *, void *));
int numcmp(char *, char *);

 

main.c

#include"Head.h"

int main(int argc, char* argv[])
{
	freopen("Example.in","r",stdin);
	
	int nlines; //问本行书
	int numberic = 0; //是否开启数字排序 
	
	if(argc > 1 && strcmp(argv[1],"-n") == 0)
		numberic = 1;
	if((nlines = readline(lineptr,MAXLINE)) >= 0)
	{
			qqsort((void **)lineptr,0,nlines-1,
			       (int (*)(void *,void*))(numberic ? numcmp : strcmp));
   			writeline(lineptr,nlines);
   			return 0;
	}
	else
	{
		printf("input too big to sort\n");
		return 1;
	}	
}

 

qsort.c

#include"Head.h"

void swap(void * v[], int a, int b)
{
	void *tmp;
	tmp = v[a];
	v[a] = v[b];
	v[b] = tmp; 
}


void qqsort(void *v[], int left, int right, int (*comp)(void *,void *)) //qsort函数名字和库函数重名更名为qqsort 
{
	int i,last;
	
	if( left >= right)
		return;
	
	swap(v,left,(left+right)/2);
	last = left;
	for(i = left + 1; i <= right; ++i)
		if(comp(v[i],v[left]) < 0)
			swap(v,++last,i);
	swap(v,left,last);
	qqsort(v,left,last-1,comp);
	qqsort(v,last+1,right,comp);
}

 

write&readline.c

#include"Head.h"

int readline(char *lineptr[], int nlines)
{
	char line[MAXLEN];
	int len;
	int lineno = 0;
	
	while(--nlines >= 0 && (len = getline(line,MAXLEN)) > 0)
	{
		if(line[len-1] == '\n')
			line[len - 1] = '\0';
		len = len -1;
		char *p = (char *)malloc(sizeof(char)*len);
		if(!p) 
		{
			printf("the memory is full\n");
			exit(1);
		}
		strcpy(p,line);
		lineptr[lineno++] = p;
	}
	return lineno;
}

void writeline(char *lineptr[], int nlines)
{
	int i;
	for(i = 0; i < nlines; ++i)
		printf("%s\n",lineptr[i]);
}

 

numcmp,c

#include"Head.h"

int numcmp(char *s1, char *s2)
{
	double v1 = atof(s1);
	double v2 = atof(s2);
	if(v1 < v2)
		return -1;
	else if(v1 == v2)
		return 0;
	else
		return 1;
}

 

getline.c

#include"Head.h"

int getline(char *line, int limit)
{
	int c;
	char *p = line;
	while(--limit > 0 && (c = getchar()) != EOF && c != '\n')
		*p++ = c;
	if(c == '\n')
		*p++ = c;
	*p = '\0';
	return p - line;
} 

 6.文本行排序的功能的增加,格式:sort -nfdr [+pos1] [-pos2] 

Head.c

/* sort -nfdr [+pos1] [-pos2] 
	n:  按数字大小排序
	f:  只对字母,数字和空格比较 
	d:  忽略大小写
	r:  递减排序
	[pos1, pos2)之间进行,如果pos1 = pos2 = 0,则整行进行排序 
*/

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

#define MAXLEN 100  //max of one line
#define MAXLINE 5000 // max of lines
extern char *lineptr[MAXLINE]; //存读入的文本 

#define NUMBERIC 1  //按数字大小排序 
#define DECR 2     //递减排序 
#define FOLD 4    //只对字母,数字和空格比较 
#define DIR 8    //忽略大小写 

extern char option;
extern int pos1,pos2;

int  getline(char *line, int limit);
int  readline(char *lineptr[], int lines);
void writeline(char *lineptr[], int nlines, int dec);
void qqsort(void *v[], int left, int right, int (*comp)(void *, void *));
int  numcmp(char *, char *);
int  charcmp(char *,char *);
void substr(char *s, char *t, int maxlen);

main.c

#include"Head.h"

char option = 0;
int pos1 = 0, pos2 = 0;
char *lineptr[MAXLINE];

int main(int argc, char* argv[])
{
	freopen("Example.in","r",stdin);
	
	int nlines; //行数 
	int numberic = 0; //字符比较还是数值比较 
	int c;
	
	while( --argc > 0 && ( (c =(*++argv)[0] ) == '-' || c == '+' ))
	if( c == '-' && !isdigit(*(argv[0] + 1)))
	{
		while( c = *++argv[0])
		{
			switch(c)
			{
				case 'n':
					option |= NUMBERIC;
					break;
				case 'r':
					option |= DECR;
					break;
				case 'f':
					option |= FOLD;
					break;
				case 'd':
					option |= DIR;
					break;
				default:
					printf("illegal option %c \n", c);
					printf("Usage: sort -dnfr [-pos1] [+pos2]");
					argc = 1;
					break;
			}
		}	
	}
	else if(c == '-' && isdigit(*(argv[0] + 1)))
		pos2 = atoi(argv[0]+1);
	else if((pos1 = atoi(argv[0]+1)) < 0)
		printf("Usage: sort -dnfr [-pos1] [+pos2]");
	
	if(argc || pos1 > pos2)
		printf("Usage: sort -dnfr [-pos1] [+pos2]");
	else if( (nlines = readline(lineptr,MAXLINE)) >= 0)
	{
		
		if(option & NUMBERIC)
			qqsort((void **)lineptr,0,nlines-1,(int (*)(void *, void *))numcmp);
		else
			qqsort((void **)lineptr,0,nlines-1,(int (*)(void *, void *))charcmp);
		writeline(lineptr,nlines,option & DECR);
	}
	else
	{
		printf("the input is too big to sort\n");
		exit(1);		
	}
	return 0;
}

qsort.c

#include"Head.h"

void swap(void * v[], int a, int b)
{
	void *tmp;
	tmp = v[a];
	v[a] = v[b];
	v[b] = tmp; 
}


void qqsort(void *v[], int left, int right, int (*comp)(void *,void *)) //qsort和系统的qsort冲突 
{
	int i,last;
	
	if( left >= right)
		return;
	
	swap(v,left,(left+right)/2);
	last = left;
	for(i = left + 1; i <= right; ++i)
		if(comp(v[i],v[left]) < 0)
			swap(v,++last,i);
	swap(v,left,last);
	qqsort(v,left,last-1,comp);
	qqsort(v,last+1,right,comp);
}

write&readline.c

#include"Head.h"

int readline(char *lineptr[], int nlines)
{
	char line[MAXLEN];
	int len;
	int lineno = 0;
	
	while(--nlines >= 0 && (len = getline(line,MAXLEN)) > 0)
	{
		char *p = (char *)malloc(sizeof(char)*len);
		if(!p) 
		{
			printf("the memory is full\n");
			exit(1);
		}
		strcpy(p,line);
		lineptr[lineno++] = p;
	}
	return lineno;
}

void writeline(char *lineptr[], int nlines, int dec)
{
	int i;
	if(dec == 0)
		for(i = 0; i < nlines; ++i)
			printf("%s",lineptr[i]);
	else
		for(i = nlines -1; i >= 0; --i)
			printf("%s",lineptr[i]);
}

numcmp.c

#include"Head.h"

int numcmp(char *s1, char *s2)
{
	char str[MAXLEN];
	substr(s1,str,MAXLEN);
	double v1 = atof(str);
	substr(s2,str,MAXLEN);
	double v2 = atof(str);
	if(v1 < v2)
		return -1;
	else if(v1 == v2)
		return 0;
	else
		return 1;
}

void substr(char *s, char *t, int maxlen)
{
	int len = strlen(s);
	if(pos2 > 0 && len > pos2)
		len = pos2;
	else if(pos2 > 0 && len < pos2)
	{
		printf("error: the string is too short\n");
		exit(1);
	}
	int i,j;
	for(i = 0, j = pos1; j < len; ++i,++j)
		t[i] = s[j];
	t[i] = '\0';
}

charcmp.c

#include"Head.h"

int charcmp(char *s1, char *s2)
{
	char a, b;
	int i,j,endpos;
	int dir,fold;
	fold = (option & FOLD) ? 1 : 0;
	dir  = (option & DIR)  ? 1 : 0;
//	printf("option = %d  fold = %d  dir = %d\n",option,fold,dir);
	if(pos2 > 0)
		endpos = pos2;
	else if((endpos = strlen(s1)) > strlen(s2))
		endpos = strlen(s2);
	i = j = pos1;
	do
	{
		if(dir)
		{
			while(i < endpos && !isalnum(s1[i]) && s1[i] != ' ' && s1[i] != '\0')  
				++i;
			while(j < endpos && !isalnum(s2[j]) && s2[j] != ' ' && s2[j] != '\0')  
				++j;
		}
		if(i < endpos && j < endpos)
		{
			a = fold ? tolower(s1[i]) : s1[i]; //printf("a = %c ",a);
			b = fold ? tolower(s2[i]) : s2[j]; //printf("b = %c ",b);
			++i;
			++j;
			if(a == b && a == '\0')
				return 0;			
		}

	}while(a == b && i < endpos && j < endpos);
	return a-b;
}

getline.c

#include"Head.h"

int getline(char *line, int limit)
{
	int c;
	char *p = line;
	while(--limit > 0 && (c = getchar()) != EOF && c != '\n')
		*p++ = c;
	if(c == '\n')
		*p++ = c;
	*p = '\0';
	return p - line;
} 

抱歉!评论已关闭.