题目就不写了,大概意思就是:尽量用制表符'\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()
{
    ; //已经读到的字符数
    ; //已经读到的空格数
    char c;          //当前读到的字符
    while ((c = getchar()) != EOF)
    {
        if (c != ' ')   //如果c不是一个空格
        {
            ) //如果已经读到 0 个空格
            {
                putchar(c);
                ++total;
            }
            else   //c不是一个空格,但是读到的空格数 不等于 0
            {
                ; --spaces)//输出空格
                    putchar(' ');
                spaces = ;                 //读到的空格数重新置为 0
                ++total;
                putchar(c);//输出当前读到的字符
            }
            if (c == '\n')
            {
                total = ;
                spaces = ;
            }
        }
        else //读了一个空格
        {
            ++total;
            ++spaces;

            int temp = (total-spaces) / TABSTOP;
            int nextLocation = (++temp) * TABSTOP;//下一个 制表符终止位
            if ( total< nextLocation)
                ;
            else//用'\t'填充空格
            {
                ; i < (nextLocation - (total-spaces)); i++)//为了明确输出的是'\t',用*号比较直观。
                    putchar('*');
                //putchar('\t');
                spaces = ;//读到的空格数重新置为 0
            }
        }
    }
    ;

}

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

 #include<stdio.h>

 #define TABSTOP 8    //在Console中,制表符终止位一般是8,16,24,32......
 #define MAXSIZE 1024 // char数组的最大长度

 int getline(char s[] , int size);

 int main()
 {
     char s [MAXSIZE];
     )
     {
         printf("%s",s);
         ;// 遍历s中的字符
         char temp[MAXSIZE];
         ;//记录temp中的字符的数量

         for (; s[i] != '\0'; ++i)
         {
             ) % TABSTOP ==  && s[i] == ' ')
             {
                 ;
                 while (pre > i - TABSTOP && s[pre] == ' ')
                     --pre;
                 ++pre;
                 ; j < pre; ++j)
                     temp[count++] = s[j];
                 //temp[count++] = '\t';
                 for (int j = pre; j <= i; ++j)
                     temp[count++] = '*';
             }
             ) % TABSTOP ==  && s[i] != ' ')
                 for (int k = i / TABSTOP*TABSTOP; k <= i; ++k)
                     temp[count++] = s[k];
         }
         for (int k = i / TABSTOP*TABSTOP; k < i; ++k)
             temp[count++] = s[k];
         temp[count] = '\0';
         printf("%s",temp);
     }
     ;

 }

 int getline(char s[], int size)
 {
     char c;
     int i;
     ; i < size -  && (c = getchar()) != EOF && c != '\n'; ++i)
         s[i] = c;
     if (c == '\n')
     {
         s[i] = c;
         ++i;
     }
     s[i] = '\0';
     return i;
 }

《C程序设计语言》读书笔记----习题1-21的更多相关文章

  1. 《JavaScript高级程序设计》读书笔记--前言

    起因 web编程过程使用javascript时感觉很吃力,效率很低.根本原因在于对javascript整个知识体系不熟,看来需要找些书脑补一下,同时欢迎众网友监督. 大神推荐书籍 看了博客大神们推荐的 ...

  2. 《Javascript高级程序设计》读书笔记之对象创建

    <javascript高级程序设计>读过有两遍了,有些重要内容总是会忘记,写一下读书笔记备忘 创建对象 工厂模式 工厂模式优点:有了封装的概念,解决了创建多个相似对象的问题 缺点:没有解决 ...

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

    练习1-20:编写程序detab,将输入中的制表符替换成适当数目的空格,使得空格充满到下一个制表符终止位的地方,.假设制表符终止位的位置时固定的,比如每隔n列就会出现一个终止位. 这里要理解“制表符” ...

  4. JavaScript高级程序设计(读书笔记)(一)

    本笔记汇总了作者认为“JavaScript高级程序设计”这本书的前七章知识重点,仅供参考. 第一章 JavaScript简介 JavaScript发展简史: 1995年,JavaScript诞生 19 ...

  5. 《C++primer》v5 第3章 字符串、向量和数组 读书笔记 习题答案

    本章问题 1.char *p="hello world";与char p[]="hello world"的问题. 简单说前者是一个指向字符串常量的指针,后者是一 ...

  6. 《JavaScript高级程序设计》读书笔记 ---基本包装类型

    为了便于操作基本类型值,ECMAScript 还提供了3 个特殊的引用类型:Boolean.Number 和String.这些类型与本章介绍的其他引用类型相似,但同时也具有与各自的基本类型相应的特殊行 ...

  7. Java核心技术卷一基础知识-第3章-Java的基本程序设计结构-读书笔记

    第3章 Java的基本程序设计结构 本章内容: 一个简单的Java应用程序 字符串 注释 输入输出 数据类型 控制流 变量 大数值 运算符 数组 本章主要讲述程序设计相关的基本概念(如数据类型.分支以 ...

  8. 《实战Java高并发程序设计》读书笔记

    文章目录 第二章 Java并行程序基础 2.1 线程的基本操作 2.1.1 线程中断 2.1.2 等待(wait)和通知(notify) 2.1.3 等待线程结束(join)和谦让(yield) 2. ...

  9. 《JavaScript 高级程序设计》读书笔记

    文章目录 第三章 基本语法 第四章 变量.作用域和内存问题 第五章 应用类型 1. Array 类型 2. RegExp 类型 3. Function 类型 4. String 类型 第六章 面向对象 ...

随机推荐

  1. JPA 系列教程6-单向多对多

    JPA中的@ManyToMany @ManyToMany注释表示模型类是多对多关系的一端. @JoinTable 描述了多对多关系的数据表关系. name 属性指定中间表名称 joinColumns ...

  2. hiho1246(数学求模)

    input 1<=n<=2000 a1 a2 ... an 1<=ai<=5*10e7 output n行,第i行指切成i段,每段和的最大公约数的最大值 做法:环形数组切成n段 ...

  3. Setting DPDK+OVS+QEMU on CentOS

    Environment Build Step: these packages are needed for building dpdk+ovs: yum install -y make gcc gli ...

  4. cmd下载文件

    进入cmd 输入ftp 192.168.1.200 然后按照提示输入用户名和密码 cd 进入要下载的目录 dir 看操作权限 lcd查看本地要装下载文件的目录 prompt关闭交互模式 mget da ...

  5. 基于VirtualBox 安装和配置Fuel OpenStack(V6.1)

    1.环境准备 准备一台内存较大的主机,12G以上 下载安装VirtualBox及其匹配的扩展包 virtualbox: http://download.virtualbox.org/virtualbo ...

  6. 转:Linux基本命令大全

    Linux基本命令大全   新手刚刚接触Linux的时候可能处处感到不便,不过没有关系,接触新的事物都有这样的一个过程,在你用过Linux一段时间后,你就会逐渐了解Linux其实和Windows一样容 ...

  7. 转:Selenium2.0介绍——WebDriver两种驱动浏览器的方式.

    如果之前熟悉Selenium RC,理解了Selenium RC是如何工作的,那么,当第一次接触Selenium WebDriver的时候,看到WebDriver居然可以不需要指定远端服务器的IP地址 ...

  8. 几种在shell命令行中过滤adb logcat输出的方法

    我们在Android开发中总能看到程序的log日志内容充满了屏幕,而真正对开发者有意义的信息被淹没在洪流之中,让开发者无所适从,严重影响开发效率.本文就具体介绍几种在shell命令行中过滤adblog ...

  9. 配置Eclipse支持java和xml文件的代码补全功能

    百度经验:jingyan.baidu.com 本文介绍如何配置Eclipse,使得在编写代码时无论是*.java还是*.xml文件都能够通过使用ALT+/快捷键实现代码不全的功能. 本文实验环境为:W ...

  10. POJ 1062 昂贵的聘礼详解最短路变形

    POJ上难得一见的中文题…… 思路:建立一个以0为源点的地图,那么Map[0][n]的值代表 第n号物品的价值,Map[i][j]代表用 j  替代 i 后,物品j的价值.我们认为酋长的承诺为节点 ‘ ...