鱼C论坛

 找回密码
 立即注册
查看: 1062|回复: 11

[已解决]练习 1-21 编写程序entab,将空格串替换为最少数量的制表

[复制链接]
发表于 2020-5-3 11:55:26 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
练习 1-21 编写程序entab,将空格串替换为最少数量的制表符和空格,但要保持单词之间的间隔不变
下面的代码是不是不对,应该不能直接把8个空格替换为制表符啊
#include<stdio.h>
#define MAX_ARRAY 1024
#define TAB 8
int getlines(char array[] , int maxlen);

int main()
{
    char array[MAX_ARRAY];
    int c,k,i;
    int len;
    int spacenum=0;

    while ((len = getlines(array,MAX_ARRAY)) > 0)
    {
        for ( i = 0; i < len; i++)
        {
            if (c==' ')
            {
                spacenum++;
            }
            if (c!=' ')
            {
                spacenum=0;
            }
            if (spacenum==TAB)
            {
                i-=7;
                len-=7;
                array[i] = '\t';
                for ( k = i+1;  k< len; k++)
                {
                    array[k] = array[k+3];
                }
                spacenum = 0;
                array[len]='\0';
            }
        }
       printf("%s",array); 
    }
    return 0;
}
int getlines(char array[] , int maxlen)
{
    int i,c;
    for ( i = 0; i < maxlen-1 && (c=getchar())!=EOF && c!='\n'; i++)
    {
        array[i] = c;
    }
    if (c=='\n')
    {
        array[i] = c;
        i++;
    }
    
    array[i] = '\0';
    return i;
    
}
最佳答案
2020-5-3 12:37:29
从上到下看代码,这次我只关心main函数中的变量 c
第8行没有出现c
第9行声明了 c,但是没有初值
第10行没有
第11行没有
第12行没有
第13行没有
第14行没有
第15行没有
第16行没有
第17行有一个 c==' '

那么问题来了,这个if条件成立吗?
答案是不知道,因为真的是不知道,不知道变量 c 的位置之前是什么
因为没有初始化,所以可以看成是 还是之前的值,但是我们不知道之前的值是什么

另外,给你个代码参考
#include <stdio.h>

#define TAB 8

int main(void) {
    char buf[4096];
    while(fgets(buf, 4096, stdin)) {
        int cols = 0;
        for(int i = 0; buf[i]; ++i) {
            if(buf[i] == '\t') {
                int count = TAB - (cols % TAB);
                if(count == 0) count = TAB;
                cols += count;
                while(count--)
                    putchar(' ');
            } else {
                putchar(buf[i]);
                ++cols;
            }
        }
    }
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-5-3 12:37:29 | 显示全部楼层    本楼为最佳答案   
从上到下看代码,这次我只关心main函数中的变量 c
第8行没有出现c
第9行声明了 c,但是没有初值
第10行没有
第11行没有
第12行没有
第13行没有
第14行没有
第15行没有
第16行没有
第17行有一个 c==' '

那么问题来了,这个if条件成立吗?
答案是不知道,因为真的是不知道,不知道变量 c 的位置之前是什么
因为没有初始化,所以可以看成是 还是之前的值,但是我们不知道之前的值是什么

另外,给你个代码参考
#include <stdio.h>

#define TAB 8

int main(void) {
    char buf[4096];
    while(fgets(buf, 4096, stdin)) {
        int cols = 0;
        for(int i = 0; buf[i]; ++i) {
            if(buf[i] == '\t') {
                int count = TAB - (cols % TAB);
                if(count == 0) count = TAB;
                cols += count;
                while(count--)
                    putchar(' ');
            } else {
                putchar(buf[i]);
                ++cols;
            }
        }
    }
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-3 12:57:28 | 显示全部楼层
人造人 发表于 2020-5-3 12:37
从上到下看代码,这次我只关心main函数中的变量 c
第8行没有出现c
第9行声明了 c,但是没有初值

这是题目的英文版的标准答案,我就是不理解作者的代码为什么会用一个制表符代替4个空格(在win里是8个),比如我前面有7个字符,输出制表符后不是应该占据1个空格吗,而不是固定的8个。
/******************************************************
   KnR 1-21
   --------
   Write a program "entab" which replaces strings of 
   blanks with the minimum number of tabs and blanks 
   to achieve the same spacing.

   Author: Rick Dearman
   email: rick@ricken.demon.co.uk

******************************************************/
#include <stdio.h>

#define MAXLINE 1000 /* max input line size */
#define TAB2SPACE 4 /* 4 spaces to a tab */

char line[MAXLINE]; /*current input line*/

int getline(void);  /* taken from the KnR book. */


int
main()
{
  int i,t;
  int spacecount,len;

  while (( len = getline()) > 0 )
    {
      spacecount = 0;
      for( i=0; i < len; i++)
        {
          if(line[i] == ' ')
            spacecount++; /* increment counter for each space */
          if(line[i] != ' ')
            spacecount = 0; /* reset counter */
          if(spacecount == TAB2SPACE) /* Now we have enough spaces
                                      ** to replace them with a tab
                                      */
            {
              /* Because we are removing 4 spaces and
              ** replacing them with 1 tab we move back 
              ** three chars and replace the ' ' with a \t
              */
              i -= 3; /* same as "i = i - 3" */
              len -= 3;
              line[i] = '\t';
              /* Now move all the char's to the right into the
              ** places we have removed.
              */
              for(t=i+1;t<len;t++)
                line[t]=line[t+3];
              /* Now set the counter back to zero and move the 
              ** end of line back 3 spaces
              */
              spacecount = 0;
              line[len] = '\0'; 
            }
        }
      printf("%s", line);
    }
  return 0;
}


/* getline: specialized version */
int getline(void)
{
  int c, i;
  extern char line[];
  
  for ( i=0;i<MAXLINE-1 && ( c=getchar()) != EOF && c != '\n'; ++i)
    line[i] = c;
  if(c == '\n') 
    {
      line[i] = c;
      ++i;
    }
  line[i] = '\0';
  return i;

}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-3 13:16:49 | 显示全部楼层
JerryLeeSir 发表于 2020-5-3 12:57
这是题目的英文版的标准答案,我就是不理解作者的代码为什么会用一个制表符代替4个空格(在win里是8个) ...

制表符的宽度是可以设置的,这个作者选择的制表符宽度是 4
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-3 13:17:23 | 显示全部楼层
我感觉你还是没有把问题说清楚
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-3 13:24:25 | 显示全部楼层
人造人 发表于 2020-5-3 13:17
我感觉你还是没有把问题说清楚

制表符的宽度确实可以设置,比如设置宽度为4
当我前面有三个字符“123”时,此时再输出制表符,此时制表符应该占据一个空格
而作者的代码思路是 制表符永远占据4个空格
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-3 13:33:47 | 显示全部楼层
JerryLeeSir 发表于 2020-5-3 13:24
制表符的宽度确实可以设置,比如设置宽度为4
当我前面有三个字符“123”时,此时再输出制表符,此时制表 ...

将空格串替换为最少数量的制表符和空格

是把一堆的空格替换成制表符
题目有点模糊

如果一个tab是4个空格
那么13个空格应该替换成几个制表符和几个空格?
最少数量?
那就是一个tab和9个空格?(最少数量是什么意思?)
我怎么感觉是3个tab和1个空格

总和最少?
3 + 1 的确小于 1 + 9
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-3 13:49:55 | 显示全部楼层
还是不对,还是有问题
这种情况怎么办?把字符 b 后面的6个空格替换为1个tab,把字符 4 后面的4个空格替换为1个tab  ?

GIF.gif
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-3 13:58:49 | 显示全部楼层
我输入的是
12<空格>34<空格>5<tab>
也就是说要自己写的这个程序只把5后面的空格替换成制表符?

GIF.gif
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-3 14:13:24 | 显示全部楼层
作者提供的这个程序就仅仅只是扫描空格,发现4个空格就替换成1个tab,不考虑我上面提到的那2种情况
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-5-3 14:31:34 | 显示全部楼层
GIF.gif
#include <stdio.h>

#define TAB 8

int main(void) {
    char buf[4096];
    while(fgets(buf, 4096, stdin)) {
        int space = 0;
        for(int i = 0; buf[i]; ++i) {
            if(buf[i] == ' ') {
                ++space; continue;
            }
            if(space) {
                if(i % TAB == 0) putchar('\t');
                else {
                    while(space--) putchar(' ');
                }
                space = 0;
            }
            putchar(buf[i]);
        }
    }
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-5-3 15:14:21 | 显示全部楼层

嗯嗯,了解了,比心谢谢啦
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-14 00:47

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表