JerryLeeSir 发表于 2020-5-3 11:55:26

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

练习 1-21 编写程序entab,将空格串替换为最少数量的制表符和空格,但要保持单词之间的间隔不变
下面的代码是不是不对,应该不能直接把8个空格替换为制表符啊

#include<stdio.h>
#define MAX_ARRAY 1024
#define TAB 8
int getlines(char array[] , int maxlen);

int main()
{
    char 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 = '\t';
                for ( k = i+1;k< len; k++)
                {
                  array = array;
                }
                spacenum = 0;
                array='\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 = c;
    }
    if (c=='\n')
    {
      array = c;
      i++;
    }
   
    array = '\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;
    while(fgets(buf, 4096, stdin)) {
      int cols = 0;
      for(int i = 0; buf; ++i) {
            if(buf == '\t') {
                int count = TAB - (cols % TAB);
                if(count == 0) count = TAB;
                cols += count;
                while(count--)
                  putchar(' ');
            } else {
                putchar(buf);
                ++cols;
            }
      }
    }
    return 0;
}

JerryLeeSir 发表于 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; /*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 == ' ')
          spacecount++; /* increment counter for each space */
          if(line != ' ')
          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 = '\t';
              /* Now move all the char's to the right into the
              ** places we have removed.
              */
              for(t=i+1;t<len;t++)
                line=line;
              /* Now set the counter back to zero and move the
              ** end of line back 3 spaces
              */
              spacecount = 0;
              line = '\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 = c;
if(c == '\n')
    {
      line = c;
      ++i;
    }
line = '\0';
return i;

}

人造人 发表于 2020-5-3 13:16:49

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

制表符的宽度是可以设置的,这个作者选择的制表符宽度是 4

人造人 发表于 2020-5-3 13:17:23

我感觉你还是没有把问题说清楚

JerryLeeSir 发表于 2020-5-3 13:24:25

人造人 发表于 2020-5-3 13:17
我感觉你还是没有把问题说清楚

制表符的宽度确实可以设置,比如设置宽度为4
当我前面有三个字符“123”时,此时再输出制表符,此时制表符应该占据一个空格
而作者的代码思路是 制表符永远占据4个空格

人造人 发表于 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

人造人 发表于 2020-5-3 13:49:55

还是不对,还是有问题
这种情况怎么办?把字符 b 后面的6个空格替换为1个tab,把字符 4 后面的4个空格替换为1个tab?

人造人 发表于 2020-5-3 13:58:49

我输入的是
12<空格>34<空格>5<tab>
也就是说要自己写的这个程序只把5后面的空格替换成制表符?

人造人 发表于 2020-5-3 14:13:24

作者提供的这个程序就仅仅只是扫描空格,发现4个空格就替换成1个tab,不考虑我上面提到的那2种情况

人造人 发表于 2020-5-3 14:31:34



#include <stdio.h>

#define TAB 8

int main(void) {
    char buf;
    while(fgets(buf, 4096, stdin)) {
      int space = 0;
      for(int i = 0; buf; ++i) {
            if(buf == ' ') {
                ++space; continue;
            }
            if(space) {
                if(i % TAB == 0) putchar('\t');
                else {
                  while(space--) putchar(' ');
                }
                space = 0;
            }
            putchar(buf);
      }
    }
    return 0;
}

JerryLeeSir 发表于 2020-5-3 15:14:21

人造人 发表于 2020-5-3 14:31


嗯嗯,了解了,比心谢谢啦{:5_109:}
页: [1]
查看完整版本: 练习 1-21 编写程序entab,将空格串替换为最少数量的制表