您的位置:首页 > 其它

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

2013-07-19 15:48 375 查看



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 *))

本程序的详解见:/article/7594576.html

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: