我试图从K&R C(练习1-20)中解决问题。我把原来的getline函数转换成了int detab(char s[], int lim, int tab)。函数的以下部分出现问题:

       while (i <= ttab)
        {
            s[i] = ' ';

            if (i < ttab)
            {
                ++i;
            }

            //++i; //SPIKE
        }
        //--i; //SPIKE

如果我像上面写的那样运行它-程序只是挂起,什么也不做。如果我将if (i < ttab)更改为if (i <= ttab)程序,它的行为将如我所期望的那样(i将比所需的高1)。如果我取消注释--i; //SPIKE--i; //SPIKE并注释掉:
            if (i < ttab)
            {
                ++i;
            }

然后,我对程序行为很满意,但对代码外观不满意。
#include <stdio.h>
#define MAXLINE 1000 // maximum input line size
#define TAB 5 // assumed tab length

int detab(char line[], int maxline, int TabStop);

//prints one line at a time; replaces tabs with TAB spaces
main()
{
    int len; //current line length
    char line[MAXLINE]; //current input line

    while ((len = detab(line, MAXLINE, TAB)) > 0)
    {
        printf("%s\n%d\n", line, len);
    }

    return 0;
}

// getline: read a line into s, return length, replaces each tab in the s by tablen         spaces
int detab(char s[], int lim, int tab)
{
    int c, i;
    int ttab = tab;

    for (i=0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
{
    if (c == '\t')
    {
        while (ttab < i)
        {
            ttab += tab;
        }
        while (i <= ttab)
        {
            s[i] = ' ';

            if (i < ttab)
            {
                ++i;
            }


            //++i; //SPIKE
        }
        //--i; //SPIKE
    }

    else
    {
        s[i] = c;
    }

}

if (c == '\n')
{
    s[i] = c;
    ++i;
}
s[i] = '\0';

return i;
}

我的目的是去掉:--i; //SPIKE--i; //SPIKE并用以下内容替换:
            if (i < ttab)
            {
                ++i;
            }

但为什么会导致绞刑以及如何解决?

最佳答案

如果去掉++i--i,那么当i==ttab时,您将永远循环,因为i再也不会改变。
您可以在i<ttab时循环,然后在之后添加一个特殊的i==ttab检查,或者您可以使用一个for循环,其增量为i,然后在末尾执行i--

10-07 14:57