C练习,有没有不用数组的方法?

问题描述 投票:0回答:2

我尝试遵循一些建议并开始阅读 C 编程语言书籍。 书中每章都有几个练习和结尾。

我刚刚做了以下练习:

“编写一个程序 entab,用最少数量的制表符和空格替换空格字符串,以实现相同的间距。当一个制表符或单个空格足以到达停止制表符时,会优先考虑哪一个?”

我对这个问题的解决方案如下:



#include <stdio.h>
#include <stdlib.h>
#include "detab.c"



#define MAX_L 1000 // max length of array is 999. -> [1000] is \0
#define TAB_W 4 // width of atab

void entab(void)
{
    char string[MAX_L];

    char c;
    int i = 0;
    // get string
    while((c = getchar()) != '\n')
    {
        string[i] = c;
        if(string[i] == '\n')
        {
            string[i+1] = '\0';
        }else {
            string[i] = c;
        }
        ++i;
    }
    int consecutive_spaces = 0;
    int tab_counter = 0;
    for(int j = 0; j < i; ++j)
    {
        if(string[j] == '\t')
            putchar(string[j]);
        else if(string[j] == ' ')
        {
            char ch =  string[j];
            consecutive_spaces++;
            for(int k = j; ch != ' '; k++)
            {//this never runs :(
                consecutive_spaces++;
                j = j + consecutive_spaces;
            }
            if(consecutive_spaces < 4)
            {
                for(int z = 0; z < consecutive_spaces; z++)
                    putchar(' ');
                consecutive_spaces = 0;
            }
            else
            {
                tab_counter = consecutive_spaces - TAB_W;
                for(int w = 0; w < tab_counter; ++w)
                {
                    putchar('\t');
                }
                for(int h = 0; h < tab_counter+1; h++)
                {
                    putchar(' ');
                }
                tab_counter = 0;
                consecutive_spaces = 0;
            }
        }
        else
            putchar(string[j]);
    }
}

int main()
{
    entab();
    return 0;
}

2个问题:

  1. 如何可能要到达制表符停止位,可能需要一个制表符(例如,当一个制表符或单个空白足以到达停止制表符时,将优先考虑哪一个?)?我的意思是要达到它,你需要一个空间,所以你不能选择其中之一,这是两种不同的情况。还是不?

  2. 我认为不可能直接在第一个 while 循环中执行此操作而不将其存储在数组中?或者是吗?

我对 C 编程和一般编程还很陌生,所以不要高估我的能力,我想你可以看到我不擅长它,我正在努力学习。

我不知道如何缩小程序。这似乎是一项简单的任务,但我不知道如何解决这个问题。

我认为它不能正常工作。

arrays c loops whitespace kernighan-and-ritchie
2个回答
0
投票

当一个制表符或单个空白足以到达停止制表符时,将优先考虑哪一个?

重点是减少输出的大小。由于空格和制表符的大小相同,因此并不重要。所以你想用哪个就用哪个。

我想如果不将其存储在数组中,就不可能直接在第一个 while 循环中执行此操作?或者是吗?

不需要数组。这只是跟踪三个变量的问题:

  • 当前在行中的位置。
  • 我们当前是否处于空白区域。
  • 当前空白范围从哪个位置开始。

算法

(支持空格、制表符和LF作为控制字符。)

  1. 将当前位置初始化为1。
  2. 将空白标志初始化为 0。
  3. 创建空白起始位置变量。
  4. 循环,
    1. 读取一个字符。

    2. 如果已达到 EOF,

      1. 跳出循环。
    3. 如果角色是LF,

      1. 将空白标志设置为 0。
      2. 将当前位置设置为1。
    4. 否则,

      1. 如果字符是空格,
        1. 如果 inwhitespace 标志为 false,
          1. 将空白标志设置为 1。
          2. 将空白开始设置为当前位置。
        2. 在当前位置加一。
      2. 否则,
        1. 该字符是一个制表符,
          1. 如果 inwhitespace 标志为 false,
            1. 将空白标志设置为 1。
            2. 将空白开始设置为当前位置。
          2. 在当前位置添加适当的金额。
        2. 否则,
          1. 如果 inwhitespace 标志为 true,
            1. 根据当前位置和空白起始位置计算要输出的适当数量的制表符和空格。
            2. 输出它们。
            3. 将空白标志设置为 false。
            4. 输出字符。
            5. 在当前位置加一。

0
投票

第一通知: 您包括

"detab.c"
,确保将原型存储在标头文件夹中,
"detab.h"

关于您的问题:

当一个制表符或单个空白足以到达停止制表符时,会优先考虑哪一个?

没关系,C 将

" "
视为 1 个字符,并将
"\t"
视为 1 个字符。

将输入存储在数组中

这不是必需的,但取决于您想要如何实现代码。您可以跟踪 for 循环中的空格并“随时”替换它们

像这样

#include <stdio.h>

#define TAB_WIDTH 4

void entab(void) {
    char c;
    int consecutive_spaces = 0;

    while ((c = getchar()) != '\n' && c != EOF) {
        if (c == '\t') {
            putchar(c);
            consecutive_spaces = 0;
        } else if (c == ' ') {
            consecutive_spaces++;
            if (consecutive_spaces == TAB_WIDTH) {
                putchar('\t');
                consecutive_spaces = 0; 
            }
        } else {
            putchar(c);
            consecutive_spaces = 0; 
        }
    }
}

int main() {
    entab();
    return 0;
}



© www.soinside.com 2019 - 2024. All rights reserved.