5.11.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. // 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
  2. // 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.
  3. // 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?
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. int getfine(char* s, int maxline);
  8. int divides (int a, int b);
  9. void spaces (char *in, char *out);
  10. void detab (char *in, char *out, int stops);
  11. /* getline: read a line into s, return length */
  12. int getfine(char* s, int maxline)
  13. {
  14. int c, i;
  15. for (i=0; ((c=getchar())!=EOF) && c!='\n'; i++)
  16. {
  17. *s = c;
  18. s++;
  19. }
  20. if (c == '\n')
  21. {
  22. *s = 0;
  23. ++i;
  24. }
  25. //printf("%d : len \n",i);
  26. return i;
  27. }
  28. int MAXSIZE=10000;
  29. int HOWBIGISTAB=8;
  30. int OFFSET=0;
  31. int main(int argc, char *argv[])
  32. {
  33. // while (argv!=0 && *argv!=0)
  34. // {argv--;}
  35. // -m
  36. argv++;
  37. if (argc > 1)
  38. {
  39. while (argv!=0 && *argv!=0)
  40. {
  41. if (*argv[0]=='+')
  42. {
  43. char temp[MAXSIZE];
  44. strcpy(*argv,temp);
  45. temp[0]=0; //get rid of +
  46. argv++;
  47. HOWBIGISTAB=atoi(temp);
  48. continue;
  49. }
  50. if (*argv[0]=='-')
  51. {
  52. char temp[MAXSIZE];
  53. strcpy(*argv,temp);
  54. temp[0]=0; //get rid of -
  55. argv++;
  56. OFFSET=atoi(temp);
  57. continue;
  58. }
  59. argv++;
  60. }
  61. }
  62. char c;
  63. int count=0;
  64. char foo[MAXSIZE];
  65. char bar[MAXSIZE];
  66. int maxsize=MAXSIZE;
  67. getfine(foo,maxsize);
  68. // spaces (foo, bar);
  69. detab (foo, bar, 8);
  70. printf ("bar: %s ", bar);
  71. return (0);
  72. }
  73. int divides (int a, int b)
  74. {
  75. if (b==0) return 1; //arbitrary
  76. return !(a % b == 0);
  77. }
  78. void spaces (char *in, char *out)
  79. {
  80. int tabs = 0;
  81. int spaces = 0 ;
  82. int count=0;
  83. for (; (count < MAXSIZE) && (*in == ' '); count++); //count the spaces in foo
  84. if (divides(HOWBIGISTAB,count)) //do we need remainder?
  85. {
  86. tabs=count/HOWBIGISTAB;
  87. spaces=0;
  88. }
  89. else
  90. {
  91. tabs=count/HOWBIGISTAB;
  92. spaces=count%HOWBIGISTAB;
  93. }
  94. int i=0;
  95. for (; i<tabs; i++)
  96. {
  97. *out='\t';
  98. out++;
  99. }
  100. for (; i<spaces; i++)
  101. {
  102. *out=' ';
  103. out++;
  104. }
  105. }
  106. void detab (char *in, char *out, int stops)
  107. //input, a string with possibly some tabs
  108. //output, a string that has, wherever there's a tab, it justifies to the next 'tab stop', which occur every 'stops' spaces.
  109. {
  110. int pos=0;
  111. while (in!=0)
  112. {
  113. if (*in == 0) break;
  114. if (*in == '\t')
  115. { // we justify to the next spot in 'out', adding
  116. while (!divides(stops, pos) && (pos > OFFSET)) //are we not at a stop?
  117. {
  118. pos++;
  119. *out=' ';
  120. out++;
  121. }
  122. // we are at a stop now, stop adding spaces
  123. in++;
  124. }
  125. else
  126. {
  127. *out=*in;
  128. out++; //gotta also overwrite something other than the first output character
  129. pos++;
  130. in++; //next symbol
  131. }
  132. }
  133. }