《C程序设计语言》读书笔记----习题1-21

题目就不写了,大概意思就是:尽量用制表符'\t'替换掉字符串中的空格。

同学们需要注意的是,打印一个制表符'\t',其所占长度不是固定的。

这里要理解“制表符”和“制表符终止位”。“制表符”的作用是使得光标移动到下一个“制表符终止位”上。举个例子,假设制表符终止位是4、8、12、16......已经已经输入了10个字符,然后按一下Tab键,那么光标会移动到位置12上,同学们新建一个文本文档试一下就了解了。

这个题目看似简单,但是写一个简单、清晰的程序还是需要花一点脑筋的。

/*
这个程序看似简单,但是写一个简单、清晰的程序还是需要花一点脑筋的。
要去思考:什么情况下可以用一个'\t'代替空格?事实上只有两种情况,那就是:

  1、当一个“非空格字符”和该字符的下一个制表符终止位之间全部都是空格的时候,就可以用
  一个制表符'\t'替换这些空格

  例如:(用 _ 代表一个空格,用 | 表示制表符终止位,注意 | 并不是字符串的一部分)
  _ _ _ a b c _ _ | _ b c d f t q u r | _ d 
  
  能够用制表符替换的空格只有:(用 * 号 表示用制表符替换掉的空格)
  _ _ _ a b c * * | _ b c d f t q u r | _ d
2、当两个制表符终止位之间全部都是空格的时候。这些空格就可以用'\t'替换。

例如:
_ _ _ _ _ a b c | _ _ _ _ _ _ _ _ | a b c

替换之后:
_ _ _ _ _ a b c | * * * * * * * * | a b c
*/ #include<stdio.h> #define TABSTOP 8 //在Console中,制表符终止位一般是8,16,24,32...... int main() { int total = 0; //已经读到的字符数 int spaces = 0; //已经读到的空格数 char c; //当前读到的字符 while ((c = getchar()) != EOF) { if (c != ' ') //如果c不是一个空格 { if (spaces == 0) //如果已经读到 0 个空格 { putchar(c); ++total; } else //c不是一个空格,但是读到的空格数 不等于 0 { for (; spaces > 0; --spaces)//输出空格 putchar(' '); spaces = 0; //读到的空格数重新置为 0 ++total; putchar(c);//输出当前读到的字符 } if (c == '\n') { total = 0; spaces = 0; } } else //读了一个空格 { ++total; ++spaces; int temp = (total-spaces) / TABSTOP; int nextLocation = (++temp) * TABSTOP;//下一个 制表符终止位 if ( total< nextLocation) ; else//用'\t'填充空格 { for (int i = 0; i < (nextLocation - (total-spaces)); i++)//为了明确输出的是'\t',用*号比较直观。 putchar('*'); //putchar('\t'); spaces = 0;//读到的空格数重新置为 0 } } } return 0; }

 如果把一行先读到一个字符数组里面,程序还会简单一些:

 1 #include<stdio.h>
 2 
 3 #define TABSTOP 8    //在Console中,制表符终止位一般是8,16,24,32......
 4 #define MAXSIZE 1024 // char数组的最大长度
 5 
 6 int getline(char s[] , int size);
 7 
 8 int main()
 9 {
10     char s [MAXSIZE];
11     while (getline(s, MAXSIZE) != 0)
12     {  
13         printf("%s",s);
14         int i = 0;// 遍历s中的字符
15         char temp[MAXSIZE];
16         int count = 0;//记录temp中的字符的数量
17 
18         for (; s[i] != '\0'; ++i)
19         {
20             if ((i + 1) % TABSTOP == 0 && s[i] == ' ')
21             {
22                 int pre = i - 1;
23                 while (pre > i - TABSTOP && s[pre] == ' ')
24                     --pre;
25                 ++pre;
26                 for (int j = i - TABSTOP + 1; j < pre; ++j)
27                     temp[count++] = s[j];
28                 //temp[count++] = '\t';
29                 for (int j = pre; j <= i; ++j)
30                     temp[count++] = '*';
31             }
32             if ((i + 1) % TABSTOP == 0 && s[i] != ' ')
33                 for (int k = i / TABSTOP*TABSTOP; k <= i; ++k)
34                     temp[count++] = s[k];
35         }
36         for (int k = i / TABSTOP*TABSTOP; k < i; ++k)
37             temp[count++] = s[k];
38         temp[count] = '\0';
39         printf("%s",temp);
40     }
41     return 0;
42 
43 }
44 
45 int getline(char s[], int size)
46 {
47     char c;
48     int i;
49     for (i = 0; i < size - 1 && (c = getchar()) != EOF && c != '\n'; ++i)
50         s[i] = c;
51     if (c == '\n')
52     {
53         s[i] = c;
54         ++i;
55     }
56     s[i] = '\0';
57     return i;
58 }

 

转载于:https://www.cnblogs.com/wzm-xu/p/4200206.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值