欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

3.2③文本格式化

程序员文章站 2022-04-24 09:00:55
...

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题 文本格式化

题目: 文本格式化的程序
一、 需求分析

  1. 文本串非空且以文件形式存放,版面要求的参数可由用户从键盘键入或者缺省。
  2. “字”定义:字是一行中不含空 格符的最长(即任何- -端都不能再扩展-个非空格符的字符进来的)子串,例如"good1"算一个字。
  3. 控制字符“@”: 符号“@”指示它后面的正文在格式化时应另起一段排放,即空一行,并在段首缩入8个字符位置。“@”自成一个字。
  4. 输出文件中字与字之间只留一个空格符,即实现多余空格符的压缩.
  5. 在输出文件中,任何完整的字仍不能分割在两行,行尾不齐没关系,但行首要对
    齐(即左对齐),含“@“字符的例外。
  6. 如果所要求的每页页底所空行数不少于3,则将页号印在页底空行中第2行的中间位置上,否则不印。
  7. 版面要求的参数要包含:
  1. 页长(Page Length)一 每页内文字(不计页号)的行数。
  2. 页宽(Page Wedth)–每行内文字所占最大字符数。
  3. 左空白(Left Margin)–每行文字前的固定空格数。
  4. 头长(Heading Length)-- 每页页顶所空行数。
  5. 脚长(Footing Length)–每 页页底所空行数(含页号行).
  6. 起始页号(Starting Page Number)一- 首页的页号。
  1. 测试数据为一篇英语文章
    二、 概要设计
采用数组存储,故不需引用类型。
其基本操作集为:
 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");
 }

三、 函数关系
3.2③文本格式化
四、 源码:

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

五、 调试分析

  1. 本题主要问题在于文件的读入和写出问题,暴露了我c语言基础不扎实的问题,经过干中学的模式,基本掌握简单的文件处理方法,解决了我一直以来的问题

  2. 其余部分较为简单,主要问题在与换行后如何保持最后一个字是完整的字,主要方法在于抓住下一个字符是不是空白符这一个关键,还有连续的空白字符删除,可以设置一个标志,查看前一个字符是不是空格符
    六、 用户手册

  3. 操作系统为win10,执行文件main.exe

  4. 待格式化文件放入read.txt,格式化文件放入write.txt文件

  5. 输入参数可缺省
    默认值为:
    PageLength=20;
    PageWedgth=80;
    LeftMargin=10;
    HeadingLength=5;
    FootingLength=5;
    StartingPageNumber=1;

  6. 用户界面为:
    3.2③文本格式化
    七、 测试结果
    输入文件为:
    3.2③文本格式化
    输出文件为:
    3.2③文本格式化
    七.附录

3.2③文本格式化

相关标签: 3.2③文本格式化