我试图从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--
。