10、字符串输入删除末尾特殊符,清除空行
1 #include <stdio.h> 2 #define maxlength 1000 3 4 int getline(char line[]); //输入存储函数 5 int changeline(char line[], int length); //存储数组处理函数(删除行尾空格、制表符,删除空行) 6 7 int main() 8 { 9 int i; 10 int length; 11 char line[maxlength]; 12 13 for (i=0; i<maxlength; ++i) //初始清空数组 14 line[i] = '\0'; 15 16 length = getline(line); //获取输入内容的总长度 17 if (length > 1) 18 { 19 if (changeline(line, length) > 1) //判断经处理后的数组长度 20 { 21 printf("%s\n", line); //输出经处理后的输入内容 22 for (i=0; i<length; ++i) //将处理后数组内的全部空格、制表符进行替换输出,以显示现保留的这些符号是否处于每行末尾 23 { 24 if (line[i] == ' ' || line[i] == '\t') 25 line[i] = '*'; 26 else if (line[i] == '\n') 27 line[i] = '|'; 28 } 29 printf("%s\n", line); 30 } 31 32 else 33 printf("当前输入内容没有有效字符!\n"); //如果经处理后的数组长度小于1,说明处理后数组内最多也只有一个换行符,即原本的输入内容没有有效字符 34 } 35 else 36 printf("当前未输入内容!\n"); //如果输入后未经处理直接保存的数组长度小于1,说明只输入了换行或者什么都没有输入 37 38 return 0; 39 } 40 int getline(char line[]) //存储数组,存储长度 41 { 42 int i; 43 int c; 44 45 i = 0; 46 47 while ((c=getchar())!=EOF) 48 { 49 line[i] = c; 50 ++i; 51 } 52 return i; //返回实际存储长度 53 } 54 55 int changeline(char line[], int length) //被处理的数组,被处理长度 56 { 57 int i; 58 int start; //设置数组前移开始位置 59 int state; //定义查询状态,1:开始查询删除 0:删除停止 60 i = length; //设置逆向查询长度 61 62 for (; i>0; --i) 63 { 64 if (line[i] == '\n') //如果查询到换行符,说明再向前即为新的一行内容,需开始进行行尾特殊字符串查找和删除 65 state = 1; 66 else 67 state = 0; 68 69 while (state == 1) //如果当前为进行查找删除状态,则每查到一个空格、制表符、换行符,都要删除,没删除一个,需要将后续所有字符前移一位 70 { 71 --i; 72 if (line[i] == ' ' || line[i] == '\t' || line[i] =='\n') 73 { 74 for(start=i; start<=length; ++start) 75 { 76 line[start] = line[start+1]; 77 } 78 length = length-1; //删除特殊字符,后续字符前移后,现数组长度-1 79 } 80 else 81 state = 0; //如果当前状态未查找删除状态,循环逆向查找时发现了一个不是特殊字符的内容,说明已脱离行尾,在发现下一行之前,其间的特殊符号不再删除 82 } 83 } 84 return length; //返回经查找删除处理后的剩余数组长度 85 }
在每行输入的末尾都有空格和制表符,处理结果显示,行尾的这些特殊符号全部被删除,行内的特殊符号都进行了保留,空行也被删除了。
这个练习纠结了很长时间,因为不知道该怎么处理以下几个问题:
1、如何区分在行内还是在行尾,不能直接把所有的特殊符号都删除
2、在删除指定符号后,数组内这个位置该怎么处理,是替换还是移动?
3、如何区分实际输入了内容(输入的全部为空行)和根本没有输入直接就结束处理这两种情况
后来琢磨了几个对应的处理方式:
1、在逆向查询时,如果查到一个‘\n’,说明进入了新行且在行尾,需要删除其中的特殊符,在这个删除的过程中,如果遇到了其它字符,说明扫描到了输入的有效信息,在遇到下一个‘\n’之前,都是在行内,不能再查询删除了,这就需要一个常量来记录这个状态进行区分,如果处于删除状态,则查询+删除,遇到常规字符,状态切换。之后开始只查不删,直至查到下一个'\n'为止。
2、在删除一个特殊符时,就要将从这个位置开始,其后的所有内容前移一个位置。期间有尝试过把这些位置直接替换成'\0',但是在输出时,输出到第一个'\0'位置,后续的内容就不会再进行输出了。
3、输入内容获取存储和进行查找删除的函数都需要进行长度值返回
getline()函数返回的长度是实际输入的字符总长,即可以判断有没有进行输入操作,也可作为changeline()函数内的一个参数使用,用以确定逆向查找的长度和起始位置
changeline()函数也需要返回一个经处理后的字符总长,用以确定经过处理之后,是否还存在有效输入内容,如果处理完成后就剩下最后那一个换行符,那就是说明在原数组内,根本没有有效数据