If you take the ++i
and --i
out, then wheni==ttab
, you loop forever, since i
never changes again.
You could loop while i<ttab
then add a special check for i==ttab
after, or you could use a for loop which increments i
, and then does i--
at the end.
Usage of <= hangs the program, but < works fine (K&R C Exercise 1-20)
-
03-06-2022 - |
Question
I'm trying to solve problem from K&R C (Exercise 1-20). I've transformed original getline
function into int detab(char s[], int lim, int tab)
. Problems occur in the following part of function:
while (i <= ttab)
{
s[i] = ' ';
if (i < ttab)
{
++i;
}
//++i; //SPIKE
}
//--i; //SPIKE
If I run it as written above - program just hangs and does nothing. If I change if (i < ttab)
to the if (i <= ttab)
program behaves as I expect it to (i
becomes higher by 1 than needed). If I uncomment --i; //SPIKE
and --i; //SPIKE
and comment out:
if (i < ttab)
{
++i;
}
then, I am happy with program behavior but not with code appearance.
#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;
}
My intention is to get rid of: --i; //SPIKE
and --i; //SPIKE
and replace it with:
if (i < ttab)
{
++i;
}
But why does it cause hanging and how to fix that?
La solution
Autres conseils
In your code when i value is same as ttab the code bellow is becomes a infinite loop.
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
}