I was playing around with a particular solution to the exercise to create a program that would convert whitespaces to tabs, when possible, preserving the original appearance of the text.
TABSTOP is 8 because that's the number of spaces a tab comes to on my terminal.
Anyway, this program has performed adequately in every test I could throw at it, save one:
If I input almost anything, but don't hit Enter at the end, (Instead, hitting Ctrl+D to break the input sequence), the text is 'slightly' off. In the particular case I have in mind, I had a sequence of spaces and tabs with an 'a' right before the end of the input, so I could see where the 'a' ended up after I hit Ctrl+D a few times. The 'a' was about 4 columns to the left of where it should have been, but nearly identical input with a carriage return at the end was handled correctly.
What confuses me is that -- assuming my console isn't doing anything really weird with the input -- I thought the fillarray function explicitly would check for EOF and break, to '\0' terminate the string if it found it....
I'm prolly not connecting a couple of obvious dots, but I'd like some help seeing what I'm doing wrong(Oh, yeah, and commentary on better approaches to the original problem would be nice, too.)
Code:
#include <stdio.h>
#define MAXARR 1024
#define TABSTOP 8
void fillarray(char [], int);
void parsearray(char []);
int checknumspaces(char [], int);
int main(void)
{
char charbox[MAXARR];
fillarray(charbox, MAXARR);
parsearray(charbox);
printf("\n----------------\n%s\n", charbox);
return 0;
}
void fillarray(char charbox[], int lim)
{
int i, c;
i = 0;
while((c = getchar()) != EOF && i < lim-1) {
charbox[i] = c;
i++;
}
charbox[i] = '\0';
}
void parsearray(char charbox[])
{
int m, i, s, t, n, lim;
lim = 0;
for(i = 0; charbox[i] != '\0'; i++)
lim++;
m = i = s = t = n = 0;
while(i < lim || m < lim) {
s = TABSTOP - ((i - t) % TABSTOP);
if(charbox[i] == '\t' || charbox[i] == '\n') {
charbox[m] = charbox[i];
m++, i++;
t = i;
}
else if(charbox[i] == ' ') {
n = checknumspaces(charbox, i);
if(n >= s) {
charbox[m] = '\t';
t = i;
m++, i += n;
}
else if(n == 0)
i++;
else {
charbox[m] = charbox[i];
m++, i++;
}
}
else if(charbox[i] == '\0')
break;
else {
charbox[m] = charbox[i];
i++, m++;
}
}
charbox[m] = '\0';
}
int checknumspaces(char charbox[], int i)
{
int c = 0;
while(1) {
if(c >= TABSTOP)
return c;
else if (charbox[i] == ' ')
c++, i++;
else if(charbox[i] == '\0')
return -1;
else if(charbox[i] == '\n' || charbox[i] == '\t')
return 0;
else
return c;
}
}