0

我正在尝试解决 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;
            }

但是为什么会导致挂起以及如何解决呢?

4

2 回答 2

3

如果你把++iand--i拿出来,那么 when i==ttab,你会永远循环,因为i永远不会再改变。
您可以循环 whilei<ttab然后添加一个特殊的检查 for i==ttabafter,或者您可以使用一个递增的 for 循环i,然后i--在最后执行。

于 2013-07-14T15:18:50.027 回答
0

在您的代码中,当 i 值与 ttab 相同时,下面的代码将变为无限循环。

while (i <= ttab) //if i== ttab it will come to loop body
        {
            s[i] = ' ';

            if (i < ttab) //if i == ttab  then i never going to increment 
            {
                ++i;
            }


            //++i; //SPIKE
        }
于 2013-07-14T15:41:29.533 回答