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