D
dgoodmaniii
+AMDG
I've been working hard on the entab program in K&R Exercise
1-21, and I'm happy to say I've found a solution. (I'm
pretty sure I have, anyway.) However, in the course of
doing so I compiled and ran the first two programs listed at
the clc-wiki site:
http://clc-wiki.net/wiki/K&R2_solutions:CHapter_1:Exercise_21
I'm not sure if I'm running the programs wrong or if I'm
misunderstanding the point of the exercise, but it seems to
me that neither of these really answer to the exercise.
What these two programs do is merely replace strings of
eight blanks with tabs, but no other strings of blanks. In
other words, they do the following; blanks indicate tabs,
while underscores indicate spaces.
TABS: | | | | | |
Input: |No_________is___the__________time____for
Output: |No _is___the __time____for
Sometimes this solution corresponds to that requested by
Exercise 1-21, but more often it doesn't.
As I'm reading it, Exercise 1-21 asks that *any* sequence of
blanks be replaced by the minimum number of tabs and blanks
to achieve the same spacing. In other words, they want
this:
TABS: | | | | | |
Input: |No_________is___the__________time____for
Output: |No ____is __the _time __for
So am I missing something?
I'm quite confident that the solution I've come up with is
ugly, but it does work. How do you all think it might be
improved? Thanks.
/* +AMDG */
/*
* A program that replaces a sequence of blanks by the
* minimum number of tabs and blanks necessary to achieve
* the same spacing. Gives preference to tabs when either a
* tab or a single blank would suffice to reach a tab stop.
*
* This program is released under the GNU General Public
* License, version 3.
*
*/
#include<stdio.h>
#include<string.h>
#define MAXLINE 10000
#define TABSTOP 8
int getline(char s[], int lim);
int tabreplace(char s[], int tabspot, int index);
int main(void)
{
int i; /* keep track of string index */
int j; /* keep track of tab stops */
char string[MAXLINE];
while(getline(string, MAXLINE) > 0) {
for(i=0,j=0; string != '\0'; ++i,++j)
i -= tabreplace(string,j,i);
printf("%s",string);
}
return 0;
}
int tabreplace(char s[], int tabspot, int index)
{
int i,j;
int numspaces;
if (((tabspot % TABSTOP) == 0) && (s[index] == '_')) {
for (i = index; (s == '_') && (i > (index-TABSTOP)); --i);
numspaces = (i>(index-TABSTOP)) ? index-i-1 : index-i;
if (numspaces > 0 && s[index-numspaces] == '_')
s[index-numspaces] = '\t';
else if (numspaces > 0 && s[index-numspaces] != '_')
s[index-numspaces+1] = '\t';
for(j=index-numspaces+1; s[j] != '\0'; ++j)
s[j] = s[j+numspaces-1];
s[++j] = '\0';
return numspaces-1;
}
return 0;
}
int getline(char s[], int lim)
{
int c, i;
for (i=0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s = c;
if (c == '\n')
s[i++] = c;
s = '\0';
return i;
}
Even now I see that I don't need string.h (at one point the
program used strlen(), but no more), and that the "j" index
in tabreplace() could just as easily reuse "i". Anything
else?
I've been working hard on the entab program in K&R Exercise
1-21, and I'm happy to say I've found a solution. (I'm
pretty sure I have, anyway.) However, in the course of
doing so I compiled and ran the first two programs listed at
the clc-wiki site:
http://clc-wiki.net/wiki/K&R2_solutions:CHapter_1:Exercise_21
I'm not sure if I'm running the programs wrong or if I'm
misunderstanding the point of the exercise, but it seems to
me that neither of these really answer to the exercise.
What these two programs do is merely replace strings of
eight blanks with tabs, but no other strings of blanks. In
other words, they do the following; blanks indicate tabs,
while underscores indicate spaces.
TABS: | | | | | |
Input: |No_________is___the__________time____for
Output: |No _is___the __time____for
Sometimes this solution corresponds to that requested by
Exercise 1-21, but more often it doesn't.
As I'm reading it, Exercise 1-21 asks that *any* sequence of
blanks be replaced by the minimum number of tabs and blanks
to achieve the same spacing. In other words, they want
this:
TABS: | | | | | |
Input: |No_________is___the__________time____for
Output: |No ____is __the _time __for
So am I missing something?
I'm quite confident that the solution I've come up with is
ugly, but it does work. How do you all think it might be
improved? Thanks.
/* +AMDG */
/*
* A program that replaces a sequence of blanks by the
* minimum number of tabs and blanks necessary to achieve
* the same spacing. Gives preference to tabs when either a
* tab or a single blank would suffice to reach a tab stop.
*
* This program is released under the GNU General Public
* License, version 3.
*
*/
#include<stdio.h>
#include<string.h>
#define MAXLINE 10000
#define TABSTOP 8
int getline(char s[], int lim);
int tabreplace(char s[], int tabspot, int index);
int main(void)
{
int i; /* keep track of string index */
int j; /* keep track of tab stops */
char string[MAXLINE];
while(getline(string, MAXLINE) > 0) {
for(i=0,j=0; string != '\0'; ++i,++j)
i -= tabreplace(string,j,i);
printf("%s",string);
}
return 0;
}
int tabreplace(char s[], int tabspot, int index)
{
int i,j;
int numspaces;
if (((tabspot % TABSTOP) == 0) && (s[index] == '_')) {
for (i = index; (s == '_') && (i > (index-TABSTOP)); --i);
numspaces = (i>(index-TABSTOP)) ? index-i-1 : index-i;
if (numspaces > 0 && s[index-numspaces] == '_')
s[index-numspaces] = '\t';
else if (numspaces > 0 && s[index-numspaces] != '_')
s[index-numspaces+1] = '\t';
for(j=index-numspaces+1; s[j] != '\0'; ++j)
s[j] = s[j+numspaces-1];
s[++j] = '\0';
return numspaces-1;
}
return 0;
}
int getline(char s[], int lim)
{
int c, i;
for (i=0; i<lim-1 && (c=getchar())!=EOF && c!='\n'; ++i)
s = c;
if (c == '\n')
s[i++] = c;
s = '\0';
return i;
}
Even now I see that I don't need string.h (at one point the
program used strlen(), but no more), and that the "j" index
in tabreplace() could just as easily reuse "i". Anything
else?