《C程序设计语言》 练习1-20
问题描述
Write a program detab that replaces tabs in the input with the proper number of blanks to space to the next tab stop. Assume a fixed set of tab stops, say every n columns. Should n be a variable or a symbolic parameter?
编写一个程序detab,用正确的空格数替换输入中的制表符,直到下一个制表符停止。假设一组固定的制表符停止,比如每n列一次。n应该是一个变量还是一个符号参数?
解题思路
其实我刚开始做这道题的时候,根本读不懂题目,以为就是把制表符替换成空格而已,其实这个思路也不是完全错误。
首先,我们要知道制表符是什么东西,具体内容我不多说,请自行谷歌,我单说一下对做这道题用到的地方。一般在计算机中,制表符是占据8列的,也就是显示器上8个字符长度的一段位置,但它又不是每次输入都会占据8个字符,下面我们举例说明:
(为了视图方便,我用*代替空格)
当我们再屏幕上输入”1234″之后按下Tab键,光标一次跳跃4列(8-4=4)
1234****
当我们输入”1234567″之后按下Tab键,光标一次跳跃1列(8-7=1)
1234567*
当我们输入13个a之后再按下Tab键,光标一次跳跃3列(16-13=3)
aaaaaaaaaaaaa***
不难看出,设备规定\t定位到8字符整数倍数处
大致了解了制表符之后,我们进行下一步的思考,把制表符替换为空格,制表符占据的空格数目还不唯一,怎么确定替换制表符的空格的数目呢?其实很简单,我们可以定义一个整形变量textplace,来标记某个字符在输入框中的位置。
比如你输入了15个字符后,按下了Tab键,此时光标跳跃1列,因为输入15个字符后,距离8的倍数16,还有1列,所以输出一个空格。
那么怎么让计算机得出距离16还有1列呢?
我们让15%8,取余后结果为7,再用定值8去减掉7,就是1了
所以计算空格的公式为:空格数目=8 – (textplace % 8);
代码如下:
#include<stdio.h> #include<stdlib.H> #include<string.h> #define TAB_SIZE 8 //一般制表符\t占8列 #define MAX_ARRAY 1000 //数组的最大范围 int getlines(char[],int maxlen);//创建一个函数,将输入的字符读入到数组中 int main() { char array[MAX_ARRAY]; int i,k;//计数器 int textplace=0;//标记字符处于哪个位置 int spacesnum;//空格数目 while (getlines(array , MAX_ARRAY) > 0) { //找出制表符的位置,并打印空格,不是制表符直接打印 for ( i = 0 , textplace = 0; array[i]!='\0'; i++) { if (array[i] == '\t') { spacesnum = TAB_SIZE - (textplace % TAB_SIZE); for ( k = 0; k < spacesnum; k++) { putchar(' '); textplace++; } }else { putchar(array[i]); textplace++; } } } return 0; } int getlines(char array[],int maxlen) { int i,c; //将输入字符读进数组,并返回数组实际长度 for(i = 0;i < maxlen-1 && (c=getchar())!=EOF && c != '\n';i++) //maxlen-1是因为最后一位要存放'\0' { array[i] = c; } if (c=='\n') { array[i] = c; i++; } array[i] = '\0'; return i; }
执行结果