您的位置:首页 > 其它

c 语言练习__去掉多余的空白字符_修正

2013-07-26 16:27 323 查看
#include <stdio.h>
#include <string.h>
#include <errno.h>

#define BUF_SIZE 128
/*
* 要求:处理一个字符串,删除字符串中多余的空格、'\t'和空行,并满足下列要求:
*    (1)对原字符串只能进行一次扫描。
*    (2)不允许申请新的空间。(这个有点疑问,声明变量也会申请空间的。)
*    (3)处理后的字符串的首尾不能有空格、'\t'和空行。
*    (4)如果原字符串中连续出现空格和'\t',则处理后的字符串只需存储一个空格。
*    (5)如果原字符串中连续出现空格、'\t'和空行,则处理后的字符串只需存储一个空行
*    (对这个空行理解也不清楚是一个\n,还是两个\n?,字符串后两个\n才会出一
*     个可见的空行,这个地方可能是 \n 我以为)。
*
*    这个题花了我两个小时,写了三遍。
*    总结:    1.对问题的理解很重要.
*        2.把问题转换成合理的模型,可以减少许多工作.
*        3.每个局部都正确,不代表整体有意义.
*
*    这个题的处理模型就是字符串拷贝。
*    但有条件.就是上面说的,转换成程序是这样的。。。。看代码吧,
*    写的注释都多余.
*
*    关于 bug 为何不直接修正,因为我看人家都只给的函数。
*/

/*
* FIXME: 如果修正bug 的话,这里将会修改成
* -----------
* char remove_extra_space(char *str, int is_trim_header)
* -----------
*/
void remove_extra_space(char *str)
{
char *s = str;    //代表生成的字符串,因为 s 多表示临时字符串。
char *prv = NULL;    //代表上一个有效的字符.这个有效的是指...(你应该明白的)

for(; prv==NULL ||*prv != '\0'; ++str){    //这个的好处在于 不会遗忘掉 ++str.而且 continue 后还能执行.
switch (*str){

case '\t': *str = ' ';    //方便统一处理.因为结果都是空格
case ' ' :
/*
* FIXME: 如果修正bug 的话,这里将会修改成
* -----------
* if ( (prv == NULL && is_trim_header != 0) || *prv == '\n' || *prv ==' '){
* -----------
*/
if (prv == NULL || *prv == '\n' || *prv ==' '){
continue;
}
break;

case '\0':
case '\n':
if (prv == NULL){
/*
* FIXME: 如果修正bug 的话,这里将会修改成
* -----------
* if (*str == '\n' && is_trim_header != 0)
* -----------
*/
if (*str == '\n')
continue;
}
else if ( *prv == ' ' || *prv == '\n'){
*prv = *str;
/*
* FIXME:这个地方获取返回值,返回值初始值 '\0'
*/
continue;
}
break;
}

if (s != str){
*s = *str;
}
prv = s;
++s;
}
/*
* FIXME: 返回返回值.
*/
}

int main(int argc,char *argv[])
{
char read_buf[BUF_SIZE] = {'\0'};
int read_size = 0;

errno = 0;

while ((read_size = fread(read_buf, sizeof (char), BUF_SIZE-1, stdin)) >0){
read_buf[read_size] = '\0';

/*
* FIXME:注意这个地方有 bug, 读取文件被分成 BUF_SIZE 的小块,
* 如果刚好在有空格(或 '\t' )处分割,则会缺少个空格.
* 如果在换行前分割,会丢失换行.
* 解决放案是传入个 int is_trim_header (是否消除字符串开始处的空白或换行);
* 如果 is_trim_header 不为 0 则 不保留开始处的空格,
* 为 0 则 按照空格是出现在句子中间或末尾的情况处理.
*
* 这里要判断行上次行末,和这次行首是否有空白符用来确定 is_trim_header 的值.
* 这里还需要 remove_extra_space 返回读到 \0 时删掉的字符,才能确定如何补偿
* 空格还是回车
*
*
*  if (上行删掉的是\n && 本行有内容) 补偿 \n,is_trim_header = 1;
*  else if (上行删掉的是' ' && 本行有内容)  is_trim_header = 0;
*  else is_trim_header = 1;
*/

remove_extra_space(read_buf);

printf("%s",read_buf);
}

if (errno != 0){
printf(strerror(errno));
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐