|
@@ -0,0 +1,150 @@
|
|
|
+// Exercise 1-21. Write a program entab that replaces strings of blanks by the minimum number of tabs and blanks to achieve the same spacing
|
|
|
+
|
|
|
+// Exercise 5-11. Modify the program entab and detab (written as exercises in Chapter 1) to accept a list of tab stops as arguments. Use the default tab settings if there are no arguments.
|
|
|
+
|
|
|
+// Use the same tab stops as for detab. When either a tab or a single blank would suffice to reach a tab stop, which should be given preference?
|
|
|
+
|
|
|
+#include <stdio.h>
|
|
|
+#include <stdlib.h>
|
|
|
+#include <string.h>
|
|
|
+int getfine(char* s, int maxline);
|
|
|
+int divides (int a, int b);
|
|
|
+void spaces (char *in, char *out);
|
|
|
+void detab (char *in, char *out, int stops);
|
|
|
+ /* getline: read a line into s, return length */
|
|
|
+ int getfine(char* s, int maxline)
|
|
|
+ {
|
|
|
+ int c, i;
|
|
|
+ for (i=0; ((c=getchar())!=EOF) && c!='\n'; i++)
|
|
|
+ {
|
|
|
+ *s = c;
|
|
|
+ s++;
|
|
|
+ }
|
|
|
+ if (c == '\n')
|
|
|
+ {
|
|
|
+ *s = 0;
|
|
|
+ ++i;
|
|
|
+ }
|
|
|
+ //printf("%d : len \n",i);
|
|
|
+ return i;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+int MAXSIZE=10000;
|
|
|
+int HOWBIGISTAB=8;
|
|
|
+int OFFSET=0;
|
|
|
+
|
|
|
+int main(int argc, char *argv[])
|
|
|
+{
|
|
|
+ // while (argv!=0 && *argv!=0)
|
|
|
+ // {argv--;}
|
|
|
+ // -m
|
|
|
+ argv++;
|
|
|
+ if (argc > 1)
|
|
|
+ {
|
|
|
+ while (argv!=0 && *argv!=0)
|
|
|
+ {
|
|
|
+ if (*argv[0]=='+')
|
|
|
+ {
|
|
|
+ char temp[MAXSIZE];
|
|
|
+ strcpy(*argv,temp);
|
|
|
+ temp[0]=0; //get rid of +
|
|
|
+ argv++;
|
|
|
+ HOWBIGISTAB=atoi(temp);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (*argv[0]=='-')
|
|
|
+ {
|
|
|
+ char temp[MAXSIZE];
|
|
|
+ strcpy(*argv,temp);
|
|
|
+ temp[0]=0; //get rid of -
|
|
|
+ argv++;
|
|
|
+ OFFSET=atoi(temp);
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ argv++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ char c;
|
|
|
+ int count=0;
|
|
|
+ char foo[MAXSIZE];
|
|
|
+ char bar[MAXSIZE];
|
|
|
+ int maxsize=MAXSIZE;
|
|
|
+ getfine(foo,maxsize);
|
|
|
+ // spaces (foo, bar);
|
|
|
+ detab (foo, bar, 8);
|
|
|
+ printf ("bar: %s ", bar);
|
|
|
+ return (0);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+int divides (int a, int b)
|
|
|
+{
|
|
|
+ if (b==0) return 1; //arbitrary
|
|
|
+ return !(a % b == 0);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void spaces (char *in, char *out)
|
|
|
+{
|
|
|
+ int tabs = 0;
|
|
|
+ int spaces = 0 ;
|
|
|
+ int count=0;
|
|
|
+ for (; (count < MAXSIZE) && (*in == ' '); count++); //count the spaces in foo
|
|
|
+
|
|
|
+ if (divides(HOWBIGISTAB,count)) //do we need remainder?
|
|
|
+ {
|
|
|
+ tabs=count/HOWBIGISTAB;
|
|
|
+ spaces=0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ tabs=count/HOWBIGISTAB;
|
|
|
+ spaces=count%HOWBIGISTAB;
|
|
|
+ }
|
|
|
+
|
|
|
+ int i=0;
|
|
|
+ for (; i<tabs; i++)
|
|
|
+ {
|
|
|
+ *out='\t';
|
|
|
+ out++;
|
|
|
+ }
|
|
|
+ for (; i<spaces; i++)
|
|
|
+ {
|
|
|
+ *out=' ';
|
|
|
+ out++;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+void detab (char *in, char *out, int stops)
|
|
|
+//input, a string with possibly some tabs
|
|
|
+//output, a string that has, wherever there's a tab, it justifies to the next 'tab stop', which occur every 'stops' spaces.
|
|
|
+{
|
|
|
+ int pos=0;
|
|
|
+ while (in!=0)
|
|
|
+ {
|
|
|
+ if (*in == 0) break;
|
|
|
+
|
|
|
+ if (*in == '\t')
|
|
|
+ { // we justify to the next spot in 'out', adding
|
|
|
+ while (!divides(stops, pos) && (pos > OFFSET)) //are we not at a stop?
|
|
|
+ {
|
|
|
+ pos++;
|
|
|
+ *out=' ';
|
|
|
+ out++;
|
|
|
+ }
|
|
|
+ // we are at a stop now, stop adding spaces
|
|
|
+ in++;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ *out=*in;
|
|
|
+ out++; //gotta also overwrite something other than the first output character
|
|
|
+ pos++;
|
|
|
+ in++; //next symbol
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|