/*//
文件名: noblank.c v0.2
作者: 苏晓(suxiaojack)
日期: 2008.7
用途: 移去文本中空行
许可 ( License ): GPL
v0.2
添加智能分段功能:
所谓只能分段:如果这一段开始,而上一段很长并且结束没有结束标记则合并两段。
//*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char buf[1024*1024*20];
int paraword=0;
int testendmark(char* start)
{
int testbuf=0;
char* p=(char*)&testbuf;
char* ends[4]={"。","!","?","”"};
int i;
int ret=0;
memcpy(p,start,2);
for(i=0;i<4;i++)
{
if(strstr(p,ends[i])==p)
{
ret=1;
break;
};
};
return ret;
};
int mayblankline(char* stream)
{
char tmp[4096];
int type;
char* s=stream;
char* s2=stream;
char* firstblank=0;
//连续的换行和空白为空白行。
//可能是从空白开始搜索的
//连续的空白之后紧接非换行,则不应当视为空白行消去,而应该显示。
int line=0;
int endmark=0;
//首先判断分段否,上一段20个中文字符内视为人为分段。
if(40<=paraword)
{
s2--;
if(*s2=='.'||*s=='!'||*s=='?'||*s=='"')
{
endmark=1;
}else
{
s2--;
if(testendmark(s2)==1)
{
endmark=1;
};
};
if(endmark==1)
{
//printf("有分段标记");
};
}else
{
//很短小的一段
//是人为分段
endmark=1;
};
//
while(*s=='/r'||*s=='/n'||*s=='/t'||*s==' ')
{
//如果这是第一个空白,记录下来.
if( ( (*s=='/t'||*s==' ') && (*(s-1)=='/r'||*(s-1)=='/n') ) || ( (*s=='/t'||*s==' ') && firstblank==0) )
{
firstblank=s;
};
if(*s=='/r'||*s=='/n')
{
if(line==0)
{
//第一次遇上了换行,判断一下换行是什么样的
paraword=0;
if(*s=='/r' && *(s+1) =='/n')
{
type==2;
}else
{
if(*s=='/n')
type=3;
else
type=1;
};
if(type==2)
{
s++;
};
line++;
}else
{
if(type==2)
s++;
line++;
}
};
s++;
};
//s现在不是空的东西了.
//跳过了所有连续的换行和空白但是:
if(line==0)
{
//根本不是空行咯。
//把空格什么的该输出的就输出拉
memcpy(tmp,firstblank,s-firstblank);
tmp[s-firstblank]=0;
printf("%s",tmp);
}else
{
//是有空行和空格。
if(endmark)
{//应该分段
switch(type)
{
case 1:
printf("%c",'/r');
break;
case 2:
printf("%s","/r/n");
break;
case 3:
printf("%c",'/n');
break;
};
if(*(s-1)==' '||*(s-1)=='/t')
{
//在一个行的起始有空白输出它
//哈哈,并且我们只输出2个空白。
//
printf("%s"," ");
};
};
};
//返回当前的位置。
return s-stream;
};
void flatprint(char* stream)
{
char *s=stream;
while(*s)
{
if(*s =='/r'|| *s=='/n' || *s==' '|| *s=='/t')
{
int may=mayblankline(s);
s+=may;
}else
{
printf("%c",*s);
paraword++;
s++;
};
};
};
int main(int argc,char* argv[])
{
int pos=0;
int c;
FILE* fp;
if(argc==2)
{
fp=fopen(argv[1],"r");
if(!fp)
{
fp=stdin;
};
}else
{
fp=stdin;
};
while( (c=getc(fp)) != EOF)
{
buf[pos++]=(char)c;
};
buf[pos]=0;
flatprint(buf);
if(fp!=stdin)fclose(fp);
return 0;
};