湖南大学c语言文本分栏程序设计报告Word格式文档下载.docx
《湖南大学c语言文本分栏程序设计报告Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《湖南大学c语言文本分栏程序设计报告Word格式文档下载.docx(17页珍藏版)》请在冰豆网上搜索。
在此模块当中,将已经处理好的数据输出到屏幕让用户预览,并输出到输出文件当中。
系统功能模块图:
(二)输入模块设计:
1、输入输出文件输入:
提示用户输入输入输出文件的文件名,并用字符型数组保存文件名。
再调用fopen函数用只读的形式打开输入文件,用只写的形式打开输出文件,并判断文件打开是否错误。
2、分栏数输入:
提示用户输入分栏数,并用一个整型的变量存储用户的输入。
3、输入页宽:
提示用户输入页宽值,页宽默认值为80,80为上限。
4、输入栏宽:
提示用户输入栏宽值,并用一个整型变量存储该值。
5、输入行数:
提示用户输入每一页的行数,用整型变量存储该值
。
6、输入每一页上下的留空数:
提示用户输入留空数的值,用整型变量存储该值。
读取模块设计:
首先定义循环,让fgets()函数不断读取用户所提供的文件,当读到返回为EOF结束。
将读取的文件首先存储在一个字符型的二维数组中。
二维数组存储的是输出时每一栏中一行的字符。
但是文件读取的字符长度可能要比行宽大,因此先用一个字符型的数组存储读入的一行数据。
每次已读取80个字符或者遇到回车字符时结束。
用一个整型数组存储对应的行数的值。
对于将字符型的暂存数组处理,有两种结果,一种是暂存数组的长度大于栏宽,即每一栏的长度,要将其分割成栏宽的大小。
再存储进去。
当暂存数组中的数据存储完后,再将行数值增加1.第二种是暂存数组的长度小于或者等于栏宽,则将暂存数组中的值直接输入到字符型数组中。
由于字符型二维数组长度有限,而文件的长度在事先是不知道的。
设计为每次二维数组存储每一页的数据,当每一页的数据读完之后,则先输出二维数组再继续读入。
输出跳出的条件是二维数组的字符串数恰好等于分栏数乘以每一页行数。
当满足这个条件时则跳出继续输出。
由于存在一种情况是在暂存数组大于栏宽时,该循环中可能也存在二维数组的字符串数恰好等于该值。
因此也要跳出转往输出模块。
而且暂存数组中也可能存在没有存储的值,因此要再让一个暂存字符型数组存储暂存数组中没有读完的字符串。
读取模块流程图:
输出模块:
输出模块主要是正确地输出二维数组中已经存在的值。
有两种情况,一种是二维数组中已经存储了一页输出的值,转到输出模块。
第二种情况是二维数组没有存储到一页的字符串,但是文件已经读完。
第一种情况,由于每一页打印用户定义的行数,所以用一个for循环来打印。
然后是每一行要打印分栏数的小行,再用一个for循环来打印分栏。
在每一行前面有一个行数。
有两种情况,一种是该行数是文件中的开始行,则直接打印该数值。
第二种是行数并不是文件的开始行,则不需要打印行数。
第二种情况。
二维数组中并没有存储一页的字符串数时。
则打印的时候会出现某个或者某几个分栏中并没有字符串的情况。
这个时候处理方法是先满足前面的分栏打印满一页的行数,再去打印其他的分栏。
这个时候处理方法是用一个if语句做整体的条件。
如果循环到某个分栏的时候,二维数组中并没有存字符串的时候,就不需要打印。
输出模块流程图:
四程序部分源程序代码和调试过程
根据详细设计,编写程序如下:
#include<
stdio.h>
string.h>
stdlib.h>
intmain()
{
FILE*fp1,*fp2;
//fp1用来存储打开分栏文件指针,fp2用来存储打开结果存储文件指针.
charw[80],filename1[256],filename2[256],buffer[1001][80],temp2[80];
//w[80]暂存数组,两个filename数组用来做文件名存储.buffer作为文件输出时的暂时存储结构.
//temp2用来存储分页时留下的字符串.
intlx[1000];
//用来存储每一行的行数。
intwide=30,n=2,m=100,re=2,cj=80;
//wide为每一小行的宽度,n用来存储分栏的栏数.
//m用来存储每一页的行数,re为每一页前后的留空数.cj为页宽值.
inti=1,j=1,l,k,temp1=0;
//一些用来循环的变量.
intleng,temp=1;
//在程序中用到的一些暂时性的数据存储.
printf("
请输入要分栏的文件名:
"
);
//输入文件;
gets(filename1);
fp1=fopen(filename1,"
r"
if(fp1==NULL)
{
printf("
文件打开失败!
\n"
return1;
}
请输入输出的文件名:
//输出文件;
gets(filename2);
fp2=fopen(filename2,"
w"
if(fp2==NULL)
输出文件打开失败!
请输入分栏数:
scanf("
%d"
&
n);
if(n<
1)
输入分栏数小于1,设为1.\n如果要结束程序请输入0,若不需要请输入1:
scanf("
if(n==0)
return1;
n=2;
elseif(n>
5)
你输入的分栏数大于5,还原为5.\n如果要结束程序请输入0,若不需要请输入1:
n=5;
请输入页宽(40到80):
cj);
if(cj<
40||cj>
80)
if(cj<
40)
printf("
页宽过小:
else
页宽过大:
cj=80;
请输入栏宽:
wide);
if(wide<
5||wide>
(cj-n*5)/n)
if(wide<
输入栏宽过小.\n"
输入栏宽过大.\n"
wide=(cj-n*5)/n;
请输入每页行数,行数大于5小于200:
m);
if(m<
5||m>
200)
if(m<
输入的行数小于5.\n"
输入的行数大于200.\n"
m=100;
请输入页上下的留空数:
re);
if(re<
0||re>
10)
if(re<
0)
输入的留空数小于0.\n"
输入的留空数大于10.\n"
re=2;
lx[0]=0;
while(fgets(w,80,fp1)!
=NULL)//从文件中读入数据;
//printf("
%s"
w);
leng=strlen(w);
if(leng>
wide)//当行文件大于限定宽度时;
{
temp1=0;
for(k=0;
k<
leng;
k++)
{
for(;
(k-temp1*wide)<
wide;
buffer[i][k-temp1*wide]=w[k];
buffer[i][k-temp1*wide]='
\0'
;
//printf("
%s\n"
buffer[i]);
lx[i]=j;
i++;
k=k-1;
temp1++;
if((i-1)%(n*m)==0)
{
for(k=k+1;
temp2[k-temp1*wide]=w[k];
temp2[k-temp1*wide]='
break;
}
}
j++;
}
else{
buffer[i][k]=w[k];
buffer[i][k]='
lx[i]=j;
i++;
if((i-1)%(n*m)==0)
page%d:
temp);
//输出页码数,temp存页码数。
fprintf(fp2,"
re;
k++)//在每一页前面输出行数;
printf("
fprintf(fp2,"
for(k=1;
m+1;
k++)//每页的页码数;
for(i=0;
i<
n;
i++)//有多少栏;
if(lx[k+i*m]!
=lx[k+i*m-1])//输出前面的页码;
{
//printf("
"
//fprintf(fp2,"
printf("
%-4d"
lx[k+i*m]);
fprintf(fp2,"
}
else//若该行页码恰等于前面的页码,则输出空格;
leng=strlen(buffer[k+i*m]);
//打印该行文字;
for(temp1=0;
temp1<
temp1++)
if((buffer[k+i*m][temp1]=='
'
)||(buffer[k+i*m][temp1]=='
\n'
))//若有回车和tab,则输出空格;
{
printf("
fprintf(fp2,"
}
else
%c"
buffer[k+i*m][temp1]);
for(l=leng;
l<
l++)//在后面补充空格;
//每一行结束后输出空格;
//在每一页后面输出行数;
i=1;
temp++;
leng=strlen(temp2);
//当temp2中存有上次没有存完的数据时,继续存储;
if(leng!
=0)
if(leng>
temp1=0;
j=j-1;
for(k=0;
for(;
buffer[i][k-temp1*wide]=temp2[k];
buffer[i][k-temp1*wide]='
lx[i]=j;
i++;
k=k-1;
temp1++;
j++;
else
buffer[i][k]=w[k];
buffer[i][k]='
lx[i]=j;
i++;
temp2[0]='
//最后一页;
fprintf(fp2,"
for(k=0;
fprintf(fp2,"
temp=i;
j=0;
for(k=1;
for(i=0;
if(k+i*m<
temp)
if(lx[k+i*m]!
//fprintf(fp2,"
else//若该行页码恰等于前面的页码,则输出空格;
leng=strlen(buffer[k+i*m]);
for(temp1=0;
if((buffer[k+i*m][temp1]=='
printf("
fprintf(fp2,"
for(l=leng;
j=0;
if(j==n)
break;
fclose(fp1);
fclose(fp2);
/*system("
pause"
*/
while
(1);
return0;
}
五实验结果
最终效果如图所示:
六软件使用说明
分栏数输入:
如果输入小于1,则默认为输入错误,默认为2.若输入超过5,则默认为5.
输入页宽:
由于页宽有一定的限度,当用户输入的值过小时,则栏宽也将变得很小,则没有作用,所以默认的页宽限制为40。
当用户输入的页宽大于80或者小于40时,则还原为默认的80。
输入栏宽:
当栏宽小于5时,则会影响输出美观,所以限定最小值为5,最大值上限则根据上面的分栏数和页宽决定。
最大值上限的确定方法:
先用分栏数乘以编号所占用的宽度,再用页宽减去该值,再除以分栏数。
当用户输入的值超出范围时,则默认为最大值。
输入行数:
行数值定义在5和200之间。
当用户输入的值小于5或者大于200时,则还原为默认的值100。
输入每一页上下的留空数:
该值为了美观,不能小于0,也不能大于10。
当用户输入的值大于10或者小于0时,则还原为默认的2。
七程序设计心得与体会
刚入手这个程序时,确实无从下手,因为平常不可能接触这样的大作业,甚至对那冗长的代码有点害怕,但没办法,还得一步一步来。
首先上网查资料了解分栏程序的用途,分栏程序的各种规则,这是第一步。
接下来要想出整个程序的框架,这可把我难坏了,因为我程序学的不怎么样,而且这个程序又是由一个人独立完成,于是又是翻书又是问同学的,最后还去无所不能的XX搜索一下。
课本被重新拿了出来,去图书馆找各种参考书,还去参考其他同学的其他程序设计,希望能从中间找到一些共同点。
总体框架下是一个个小程序,每一个都不容易,不断地更改,调试,实在不会的继续找同学帮忙解决。
这一个大程序编下来,程序设计的知识绝对得到了巩固,另外我们的其他能力,例如合作能力和查阅筛选资料的能力也大大提高
附录:
参考文献
《C语言程序设计》田丽华主编清华大学出版社
《程序设计基础教程(C语言)》杨有安陈维曹慧雅编著人民邮电出版社
参考链接: