3.2③文本格式化
3.2③文本格式化
(一) [问题描述]
输入文件中含有待格式化(或称为待排版)的文本,它由多行的文字组成,例如一篇英文文章。每一行由一系列被一个或多个空格符所隔开的字组成,任何完整的字都没有被分割在两行(每行最后一个字与下一行的第一个字之间在逻辑上应该由空格分开),每行字符数不超过80。除了上述文本类字符之外,还存在着起控制作用的字符:符号“@”指示它后面的正文在格式化时应另起一段排放,即空一行,并在段首缩入8个字符位置。“@”自成一个字。一个文本格式化程序可以处理上述输入文件,按照用户指定的版面规格重排版面:实现页内调整、分段、分页等文本处理功能,排版结果存入输出文本文件中。
试写一个这样的程序。
(二) [基本要求]
(1)输出文件中字与字之间只留一个空格符,即实现多余空格符的压缩.
(2)在输出文件中,任何完整的字仍不能分割在两行,行尾不齐没关系,但行首要对
齐(即左对齐)。
(3)如果所要求的每页页底所空行数不少于3,则将页号印在页底空行中第2行的中
间位置上,否则不印。
(4)版面要求的参数要包含:
● 页长(Page Length)一 每页内文字(不计页号)的行数。
页宽(Page Wedth)–每行内文字所占最大字符数。
左空白(Left Margin)–每行文字前的固定空格数。
● 头长(Heading Length)-- 每页页顶所空行数。
脚长(Footing Length)–每 页页底所空行数(含页号行).
● 起始页号(Starting Page Number)一- 首页的页号。
(三) [测试数据]
此略。注意在标点之后加上空格符。
[实现提示]
可以设:左空白数X2+页宽≤160,即行印机最大行宽,从而只要设置这样大的一个
行缓冲区就足够了,每加工完一行,就输出一行。
如果输入文件和输出文件不是由程序规定死,而是可由用户指定,则有两种做法:一
是像其他参量一样,将文件名交互地读入字符串变量中;更好的方式是让用户通过命令
行0指定,具体做法依机器的操作系统而定。
应该首先实现GetAWord(w)这- -操 作,把诸如行尾处理、文件尾处理、多余空格符
压缩等-系列“低级”事务留给它处理,使系统的核心部分集中对付排版要求。
每个参数都可以实现缺省值零设置。上述排版参數的缺省值可以分别取56,60,10,5,
5和1.
(四) [选作内容]
(1)输入文件名和输出文件名要由用户指定。
(2)允许用户指定是否右对齐,即增加一个参量“右对齐否”(Right Justifying),缺省
值可设为“y"(yes)。右对齐指每行最后-一个字的字尾要对齐,多余的空格要均匀分布在本
行中各字之间。
(3)实现字符填充(character stuffing)技术。“@”作为分段控制符之后,限制了原文.
中不能有这样的字。现在去掉这一限制:如果原文中有这样的字,改用两个“@”并列起来
表示一个“@”字。当然,如果原文中此符号夹在字中,就不必特殊处理了。.
(4)允许用户自动按多栏印出一页. .
① 字是一行中不含空格符的最长(即任何- -端都不能再扩展-个非空格符的字符进来的)子串,例如"good1"算一个字。
② 命令行一用户在运行一个程序时所发的一个命令。它通常由一行字符组成。
③ 缺省值一当用户不愿意费心给一个参数提供数字时。他可以直接键入回车键。 这时程序自动地对该参数赋一个预定的值。这个值称为缺省值。
④ 文本一行或多行可显示字符,每行以回车符结束。
实习报告3.2题 文本格式化
题目: 文本格式化的程序
一、 需求分析
- 文本串非空且以文件形式存放,版面要求的参数可由用户从键盘键入或者缺省。
- “字”定义:字是一行中不含空 格符的最长(即任何- -端都不能再扩展-个非空格符的字符进来的)子串,例如"good1"算一个字。
- 控制字符“@”: 符号“@”指示它后面的正文在格式化时应另起一段排放,即空一行,并在段首缩入8个字符位置。“@”自成一个字。
- 输出文件中字与字之间只留一个空格符,即实现多余空格符的压缩.
- 在输出文件中,任何完整的字仍不能分割在两行,行尾不齐没关系,但行首要对
齐(即左对齐),含“@“字符的例外。 - 如果所要求的每页页底所空行数不少于3,则将页号印在页底空行中第2行的中间位置上,否则不印。
- 版面要求的参数要包含:
- 页长(Page Length)一 每页内文字(不计页号)的行数。
- 页宽(Page Wedth)–每行内文字所占最大字符数。
- 左空白(Left Margin)–每行文字前的固定空格数。
- 头长(Heading Length)-- 每页页顶所空行数。
- 脚长(Footing Length)–每 页页底所空行数(含页号行).
- 起始页号(Starting Page Number)一- 首页的页号。
- 测试数据为一篇英语文章
二、 概要设计
采用数组存储,故不需引用类型。
其基本操作集为:
Status StrAssign(SString T,char *chars )
/*生成一个其值等于chars的串T */
Status StrCopy(SString T,SString S)
/*由串S复制得串T */
Status StrEmpty(SString S)
/*若S为空串,则返回TRUE,否则返回FALSE */
int StrCompare(SString S, SString T)
/*初始条件:串S和存在*/
/*操作结果:若S>T,则返回值>0;若s=T,则返回值=0;若S<T,则返回值<θ */
int StrLength(Sstring S)
/*返回串的元素个数*/
Status ClearString(SString S)
/*初始条件:串S存在。操作结果:将s清为空串*/
Status Concat(SString T,SString S1,SString S2) /*算法4.2改*/
/*用T返回S1和52联接而成的新串。若未截断,则返回TRUE, 否则FALSE */
Status SubString(sString Sub,SString S,int pos,int len)
{/* 用Sub返回串S的第pos个字符起长度为len的子串。算法4.3单
int Index(SString s,SString T,int pos)
/*返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为。 */
/*其中,T非空,1s poss StrLength(S). 算法4.5 */
Status StrInsert(SString s,int pos,SString
/*初始条件:串S和存在,1s poss StrLength(S)+1 */
/*操作结果:在串S的第pos个字符之前插入事T。完全插入返回TRUE,部分插入返回FALSE */
Status StrDelete(SString s,int pos,int len)
/*初始条件:串s存在,15 poss StrLength(S)-Len+1 */
/*操作结果:从申S中删除第pos个字符起长度为len的子串*/
Status Replace(sString S, SString T, SString V)
/*初始条件:串S, T和V存在,T是非空串(此函数与串的存储结构无关) */
/*操作结果:用V替换主串S中出现的所有与相等的不重叠的子串*/
void Des troyString(
/*由于SString是定长类型,无法销毁*/
void StrPrint(SString T )
/*输出字符串T。另加*/
伪码实现:
Status StrAssign(SString T,char *chars)
{ /* 生成一个其值等于chars的串T */
if(strlen(chars)>MAXSTRLEN)
return ERROR;
else
{
T[0]=strlen(chars);
for(i=1;i<=T[0];i++)
T[i]=*(chars+i-1);
return OK;
}
}
Status StrCopy(SString T,SString S)
{ /* 由串S复制得串T */
for(i=0;i<=S[0];i++)
T[i]=S[i];
return OK;
}
Status StrEmpty(SString S)
{ /* 若S为空串,则返回TRUE,否则返回FALSE */
if(S[0]==0)
return TRUE;
else
return FALSE;
}
int StrCompare(SString S,SString T)
{ /* 初始条件: 串S和T存在 */
/* 操作结果: 若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0 */
for(i=1;i<=S[0]&&i<=T[0];++i)
if(S[i]!=T[i])
return S[i]-T[i];
return S[0]-T[0];
}
int StrLength(SString S)
{ /* 返回串的元素个数 */
return S[0];
}
Status ClearString(SString S)
{ /* 初始条件:串S存在。操作结果:将S清为空串 */
S[0]=0;/* 令串长为零 */
return OK;
}
Status Concat(SString T,SString S1,SString S2) /* 算法4.2改 */
{ /* 用T返回S1和S2联接而成的新串。若未截断,则返回TRUE,否则FALSE */
if(S1[0]+S2[0]<=MAXSTRLEN)
{ /* 未截断 */
for(i=1;i<=S1[0];i++)
T[i]=S1[i];
for(i=1;i<=S2[0];i++)
T[S1[0]+i]=S2[i];
T[0]=S1[0]+S2[0];
return TRUE;
}
else
{ /* 截断S2 */
for(i=1;i<=S1[0];i++)
T[i]=S1[i];
for(i=1;i<=MAXSTRLEN-S1[0];i++)
T[S1[0]+i]=S2[i];
T[0]=MAXSTRLEN;
return FALSE;
}
}
Status SubString(SString Sub,SString S,int pos,int len)
{ /* 用Sub返回串S的第pos个字符起长度为len的子串。算法4.3 */
if(pos<1||pos>S[0]||len<0||len>S[0]-pos+1)
return ERROR;
for(i=1;i<=len;i++)
Sub[i]=S[pos+i-1];
Sub[0]=len;
return OK;
}
int Index(SString S,SString T,int pos)
{ /* 返回子串T在主串S中第pos个字符之后的位置。若不存在,则函数值为0。 */
/* 其中,T非空,1≤pos≤StrLength(S)。算法4.5 */
if(1<=pos&&pos<=S[0])
{
i=pos;
j=1;
while(i<=S[0]&&j<=T[0])
if(S[i]==T[j]) /* 继续比较后继字符 */
{
++i;
++j;
}
else /* 指针后退重新开始匹配 */
{
i=i-j+2;
j=1;
}
if(j>T[0])
return i-T[0];
else
return 0;
}
else
return 0;
}
Status StrInsert(SString S,int pos,SString T)
{ /* 初始条件: 串S和T存在,1≤pos≤StrLength(S)+1 */
/* 操作结果: 在串S的第pos个字符之前插入串T。完全插入返回TRUE,部分插入返回FALSE */
if(pos<1||pos>S[0]+1)
return ERROR;
if(S[0]+T[0]<=MAXSTRLEN)
{ /* 完全插入 */
for(i=S[0];i>=pos;i--)
S[i+T[0]]=S[i];
for(i=pos;i<pos+T[0];i++)
S[i]=T[i-pos+1];
S[0]=S[0]+T[0];
return TRUE;
}
else
{ /* 部分插入 */
for(i=MAXSTRLEN;i<=pos;i--)
S[i]=S[i-T[0]];
for(i=pos;i<pos+T[0];i++)
S[i]=T[i-pos+1];
S[0]=MAXSTRLEN;
return FALSE;
}
}
Status StrDelete(SString S,int pos,int len)
{ /* 初始条件: 串S存在,1≤pos≤StrLength(S)-len+1 */
/* 操作结果: 从串S中删除第pos个字符起长度为len的子串 */
if(pos<1||pos>S[0]-len+1||len<0)
return ERROR;
for(i=pos+len;i<=S[0];i++)
S[i-len]=S[i];
S[0]-=len;
return OK;
}
Status Replace(SString S,SString T,SString V)
{ /* 初始条件: 串S,T和V存在,T是非空串(此函数与串的存储结构无关) */
/* 操作结果: 用V替换主串S中出现的所有与T相等的不重叠的子串 */
i=1; /* 从串S的第一个字符起查找串T */
if(StrEmpty(T)) /* T是空串 */
return ERROR;
do
{
i=Index(S,T,i); /* 结果i为从上一个i之后找到的子串T的位置 */
if(i) /* 串S中存在串T */
{
StrDelete(S,i,StrLength(T)); /* 删除该串T */
StrInsert(S,i,V); /* 在原串T的位置插入串V */
i+=StrLength(V); /* 在插入的串V后面继续查找串T */
}
}while(i);
return OK;
}
void StrPrint(SString T)
{ /* 输出字符串T。另加 */
int i;
for(i=1;i<=T[0];i++)
printf("%c",T[i]);
printf("\n");
}
三、 函数关系
四、 源码:
//head.h
#ifndef __TEST_H__
#define __TEST_H__
#include<time.h>
#include<string.h>
#include<malloc.h> /* malloc()等 */
#include<limits.h> /* INT_MAX等 */
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<stdlib.h> /* atoi() */
#include<math.h> /* floor(),ceil(),abs() */
#include<process.h> // exit()
// 函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
#define MAXPAGENUMBER 5
void input(int* PageLength,int* PageWedgth,int* LeftMargin,int* HeadingLength,int* FootingLength,int* StartingPageNumber);
void format(FILE *fpr,FILE *fpw,int PageLength,int PageWedgth,int LeftMargin,int HeadingLength,int FootingLength,int StartingPageNumber);
int IsTurnBlank(char* c);
void printfHeadingLength(int HeadingLength,FILE *fpw);
void printfFootingLength1(int FootingLength,FILE *fpw);
void printfFootingLength2(int PageWedgth,int LeftMargin,int PageNumber,int FootingLength,FILE *fpw);
void printfLeftMargin(int LeftMargin,FILE* fpw);
#endif
int main()
{
int PageLength,PageWedgth,LeftMargin,HeadingLength,FootingLength,StartingPageNumber;
input(&PageLength,&PageWedgth,&LeftMargin,&HeadingLength,&FootingLength,&StartingPageNumber);
FILE *fpr=NULL,*fpw=NULL;
fpr=fopen("C:/tmp/read.txt","r");
fpw=fopen("C:/tmp/write.txt","w");
format(fpr,fpw,PageLength,PageWedgth,LeftMargin,HeadingLength,FootingLength,StartingPageNumber);
fclose(fpr);
fclose(fpw);
return 0;
}
void input(int* PageLength,int* PageWedgth,int* LeftMargin,int* HeadingLength,int* FootingLength,int* StartingPageNumber)
{//所有变量可以缺省,用户键入换行符即为缺省
printf("接下来输入参数:(若想设为默认值,可直接按回车)\n");
system("pause");
*PageLength=20;
*PageWedgth=80;
*LeftMargin=10;
*HeadingLength=5;
*FootingLength=5;
*StartingPageNumber=1;
char *s=(char*)malloc(sizeof(char)*5);
printf("每页内文字(不计页号)的行数为:\n");
gets(s);
if(s[0]!='\0') *PageLength=atoi(s);
printf("每行内文字所占最大字符数为:\n");
gets(s);
if(s[0]!='\0') *PageWedgth=atoi(s);
printf("每行文字前的固定空格数为:\n");
gets(s);
if(s[0]!='\0') *LeftMargin=atoi(s);
printf("每页页顶所空行数为:\n");
gets(s);
if(s[0]!='\0') *HeadingLength=atoi(s);
printf("每页页底所空行数(含页号行)为:\n");
gets(s);
if(s[0]!='\0') *FootingLength=atoi(s);
printf("首页的页号为:\n");
gets(s);
if(s[0]!='\0') *StartingPageNumber=atoi(s);
}
// 1) 页长(PageLength)一 每页内文字(不计页号)的行数。
// 2) 页宽(PageWedth)--每行内文字所占最大字符数。
// 3) 左空白(LeftMargin)--每行文字前的固定空格数。
// 4) 头长(HeadingLength)-- 每页页顶所空行数。
// 5) 脚长(FootingLength)--每 页页底所空行数(含页号行).
// 6) 起始页号(StartingPage Number)一- 首页的页号。
#include"head.h"
void format(FILE *fpr,FILE *fpw,int PageLength,int PageWedgth,int LeftMargin,int HeadingLength,int FootingLength,int StartingPageNumber)
{
int i;
int PageNumber=StartingPageNumber;//初始化PageNumber设为用户指定参数
int hflag=0;//判断是否需要设置页行号的标志,其实这里可以用函数指针的,但是由于懒,不想做
if(FootingLength>=3) hflag=1;//如果脚长大于等于3,设置页行号
int pageline=0;//每一页的行数,用来和pagelength比较,判断是否需要换行
char c;//当下从文件中录入待处理的c
char jc;//在行满了的时候用来判断下一个字符是不是空白符的jc
char *ch=(char*)malloc(sizeof(char)*(PageWedgth+2));//ch用来存储输出的一整行字符,末尾还有一个换行符号
ch[PageWedgth]='\n';//把ch最后一个字符设定为恒为换行符
ch[PageWedgth+1]='\0';
for(i=0;i<PageWedgth;i++)ch[i]=' ';//初始化ch为除最后一个字符外全为空格的字符
printfHeadingLength(HeadingLength,fpw);//输出第一页页顶空行数
printfLeftMargin(LeftMargin,fpw);
int pc=0,ph=0;//pc为每一行的指针,ph为当前字的长度
int bflag=0;//前一个字符是否是空格
c = fgetc(fpr);//先读一个c确保文件非空
//system("pause");
while(!feof(fpr))//输入文件还未结束时进入循环
{
if(IsTurnBlank(&c)&&bflag==0)//如果是第一次出现的空白符,输出
{
ph=0;//前一个字结束,重置字的长度
bflag=1;//标志
ch[pc]=c;
if(pc>=PageWedgth-1)//每一次入数组都要判断是否行满
{
fputs(ch,fpw);//输出当前行到输出文件
for(i=0;i<PageWedgth;i++) ch[i]=' ';//初始化ch
pageline++;//行号+1
if(pageline>=PageLength)//每一次换行都要判断是否页满,页满则换页
{
if(hflag==1) printfFootingLength2(PageWedgth,LeftMargin,PageNumber,FootingLength,fpw);//判断是否需要输出页码
else printfFootingLength1(FootingLength,fpw);
printfHeadingLength(HeadingLength,fpw);//输出页顶空行
PageNumber++;//页数+1
pageline=0;//行数置零
}
printfLeftMargin(LeftMargin,fpw);//无论是否换页,都要输出左空白
bflag=1;
pc=0;//指针置零
ph=0;//字指针置零
}
else pc++;//指针+1即可
}
else if(c=='@')//如果遇到换行标志符‘@’。先输出一个空格,@单独成字输出,后面加一个换行符
{
ch[pc]=' ';//先输出一个空格
if(pc>=PageWedgth-1)//每一次入数组都要判断是否行满
{
fputs(ch,fpw);//输出当前行到输出文件
for(i=0;i<PageWedgth;i++) ch[i]=' ';//初始化ch
pageline++;//行号+1
if(pageline>=PageLength)//每一次换行都要判断是否页满,页满则换页
{
if(hflag==1) printfFootingLength2(PageWedgth,LeftMargin,PageNumber,FootingLength,fpw);//判断是否需要输出页码
else printfFootingLength1(FootingLength,fpw);
printfHeadingLength(HeadingLength,fpw);//输出页顶空行
PageNumber++;//页数+1
pageline=0;//行数置零
}
printfLeftMargin(LeftMargin,fpw);//无论是否换页,都要输出左空白
bflag=1;
pc=0;//指针置零
ph=0;//字指针置零
}
else pc++;//否则指针后移
//ch[pc]='@';//'@'不入文件,作一行处理
fputs(ch,fpw);//输出当前行到输出文件
for(i=0;i<PageWedgth;i++) ch[i]=' ';//初始化ch
pageline++;//行号+1
if(pageline>=PageLength)//每一次换行都要判断是否页满,页满则换页
{
if(hflag==1) printfFootingLength2(PageWedgth,LeftMargin,PageNumber,FootingLength,fpw);//判断是否需要输出页码
else printfFootingLength1(FootingLength,fpw);
printfHeadingLength(HeadingLength,fpw);//输出页顶空行
PageNumber++;//页数+1
pageline=0;//行数置零
}
printfLeftMargin(LeftMargin,fpw);//无论是否换页,都要输出左空白
bflag=1;
pc=0;//指针置零
ph=0;//字指针置零
pc+=8;//输出八个空字符
bflag=1;//标志为空白符
}
else if(!IsTurnBlank(&c))//若字符不是空白符
{
if(bflag==1)//如果前一个字符是空白符
{
ph=0;//字指针归零
bflag=0;//标志
}
if(pc>=PageWedgth-1)
{
jc=fgetc(fpr);
if(IsTurnBlank(&jc))
{
ch[pc]=c;
fputs(ch,fpw);//输出当前行到输出文件
for(i=0;i<PageWedgth;i++) ch[i]=' ';//初始化ch
pageline++;//行号+1
if(pageline>=PageLength)//每一次换行都要判断是否页满,页满则换页
{
if(hflag==1) printfFootingLength2(PageWedgth,LeftMargin,PageNumber,FootingLength,fpw);//判断是否需要输出页码
else printfFootingLength1(FootingLength,fpw);
printfHeadingLength(HeadingLength,fpw);//输出页顶空行
PageNumber++;//页数+1
pageline=0;//行数置零
}
printfLeftMargin(LeftMargin,fpw);//无论是否换页,都要输出左空白
bflag=1;
pc=0;//指针置零
ph=0;//字指针置零
}
else
{
fseek(fpr,(long)(ph+2),SEEK_CUR);
//fpr->_ptr-=(ph+2);
for(i=0;i<ph;i++) ch[pc-i-1]=' ';
fputs(ch,fpw);
for(i=0;i<PageWedgth;i++) ch[i]=' ';
pageline++;
if(pageline>=PageLength)//每一次换行都要判断是否页满,页满则换页
{
if(hflag==1) printfFootingLength2(PageWedgth,LeftMargin,PageNumber,FootingLength,fpw);//判断是否需要输出页码
else printfFootingLength1(FootingLength,fpw);
printfHeadingLength(HeadingLength,fpw);//输出页顶空行
PageNumber++;//页数+1
pageline=0;//行数置零
}
printfLeftMargin(LeftMargin,fpw);
bflag=1;
pc=0;
ph=0;
}
}
else
{
ch[pc]=c;
if(pc>=PageWedgth-1)//每一次指针后移都要判断是否行满
{
fputs(ch,fpw);//输出当前行到输出文件
for(i=0;i<PageWedgth;i++) ch[i]=' ';//初始化ch
pageline++;//行号+1
if(pageline>=PageLength)//每一次换行都要判断是否页满,页满则换页
{
if(hflag==1) printfFootingLength2(PageWedgth,LeftMargin,PageNumber,FootingLength,fpw);//判断是否需要输出页码
else printfFootingLength1(FootingLength,fpw);
printfHeadingLength;//输出页顶空行
PageNumber++;//页数+1
pageline=0;//行数置零
}
printfLeftMargin(LeftMargin,fpw);//无论是否换页,都要输出左空白
bflag=1;
pc=0;//指针置零
ph=0;//字指针置零
}
else
{
ph++;
pc++;
}
}
}
c = fgetc(fpr);//最后一个c的值为-1,但是无妨,因为其他所有的循环操作都要放在此句话上面
}//while
if(pc==0) printfLeftMargin(LeftMargin,fpw);
fputs(ch,fpw);//输出当前行到输出文件
if(hflag==1) printfFootingLength2(PageWedgth,LeftMargin,PageNumber,FootingLength,fpw);//判断是否需要输出页码
else printfFootingLength1(FootingLength,fpw);
free(ch);
}
int IsTurnBlank(char* c)
{//判断是否是空白符,若是,返回1,若否,返回0;
if(*c==' ') return 1;
else if(*c=='\n'||*c=='\t')
{
*c=' ';
return 1;
}
else return 0;
}
void printfHeadingLength(int HeadingLength,FILE *fpw)
{//页顶空行输出
int i;
char *blank=(char*)malloc(sizeof(char)*HeadingLength);
for(i=0;i<HeadingLength;i++) blank[i]='\n';
fprintf(fpw,blank);
free(blank);
}
void printfFootingLength1(int FootingLength,FILE *fpw)
{//无页码的页底空行输出
int i;
char *blank=(char*)malloc(sizeof(char)*FootingLength);
for(i=0;i<FootingLength;i++) blank[i]='\n';
fprintf(fpw,blank);
free(blank);
}
void printfFootingLength2(int PageWedgh,int LeftMargin,int PageNumber,int FootingLength,FILE *fpw)
{//有页码的页底空行输出
int i;
char SPageNumber[MAXPAGENUMBER]={0};//存放页码的字符串
//SPageNumber[MAXPAGENUMBER]='\n';
fprintf(fpw,"\n");//输出一个空行
for(i=0;i<(LeftMargin+2*PageWedgh/3)-2;i++) fputc(' ',fpw);
itoa(PageNumber,SPageNumber,10);
fprintf(fpw,SPageNumber);
fputc('\n',fpw);
char *blank=(char*)malloc(sizeof(char)*FootingLength);
for(i=0;i<FootingLength-2;i++) blank[i]='\n';//接下来的行为空行
fprintf(fpw,blank);//输出空行
free(blank);
//free(pageline);
}
void printfLeftMargin(int LeftMargin,FILE* fpw)
{
int i;
for(i=0;i<LeftMargin;i++) fputc(' ',fpw);
}
五、 调试分析
-
本题主要问题在于文件的读入和写出问题,暴露了我c语言基础不扎实的问题,经过干中学的模式,基本掌握简单的文件处理方法,解决了我一直以来的问题
-
其余部分较为简单,主要问题在与换行后如何保持最后一个字是完整的字,主要方法在于抓住下一个字符是不是空白符这一个关键,还有连续的空白字符删除,可以设置一个标志,查看前一个字符是不是空格符
六、 用户手册 -
操作系统为win10,执行文件main.exe
-
待格式化文件放入read.txt,格式化文件放入write.txt文件
-
输入参数可缺省
默认值为:
PageLength=20;
PageWedgth=80;
LeftMargin=10;
HeadingLength=5;
FootingLength=5;
StartingPageNumber=1; -
用户界面为:
七、 测试结果
输入文件为:
输出文件为:
七.附录