1

This is my version of detab, from this K&R exercise:

Modify detab to accept a list of tab stops as arguments. Use the default tab setting if there are no arguments.

#include <stdio.h>
#include <stdlib.h>
#define TAB_STOP 8

/* replaces tabs from input with the proper amount of blank spots */
int Detab()
{
     int c, x;
     int column;
     x = column = 0;

     while((c=getchar())!=EOF)
     {
        if(c == '\n') /* reseting counter if newline */
        {
            putchar(c);
            return 1;
        }
        else if(c!='\t')  /* column counts places to tab spot */
        { 
             putchar(c);
             column++; 

             if(column == TAB_STOP) 
             column = 0;
        }
        else /* tab */
        {
           for(x=0; x<TAB_STOP - column; x++)
           putchar('_');

           column = 0;
        } 
     }
     return 0;
}
int main(int argc, char *argv[])
{
     int valid;

     while((valid=Detab())!=0);

     printf("Press any key to continue.\n");
     getchar();
     return 0;
}

My question is if there are more then one argument—for example 5, 8, 10—when is the next tab stop suppose to start being active? At which point should program start using TAB_STOP 8 instead of the starting 5? After a newline or how should I do this?

I'm also not really sure if I should put all of this into main, or should I stick with a separate function?

Edit: ok this is what i tried.

#define MAX_ARGUMENTS 100
int main(int argc, char *argv[])
{
     int i, val = 0;
     int nums[MAX_ARGUMENTS];
     int x = 0;

     for(i = 1; i < argc; i++) {

           while(isdigit(*argv[i])) {
             val = val * 10 + *argv[i] - '0';
             *++argv[i];
           }

           nums[x++] = val;
           val = 0;

     }

     Detab(nums);       


     printf("Press any key to continue.\n");
     getchar();
     return 0;
}

Am i on the right track? Can this work? I still havent modified detab.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Tool
  • 12,126
  • 15
  • 70
  • 120
  • How exactly should i implement this. Should i put all this code in main and then first process everything thats in argc/argv and then continue with normal detab? – Tool Jan 07 '10 at 23:11
  • I was maybe thinking of storing the numbers in a one dimensional array in main and then passing that array to Detab(), which then changes the argument TAB_STOP until it reaches \0. Just an idea. – Tool Jan 07 '10 at 23:15
  • You might want to put your second question into a .. second question. :) "How to pass a variable number of parameters to a function?" "How do I modify Detab to do X?" would be possible titles *but also areas you should search* for previously asked questions (especially the first). –  Jan 07 '10 at 23:25
  • Specifically, you can use varargs ("variadic functions" is also a good search term for that) or pass an array and a length (the latter is almost always preferred in your situation), to pass multiple values to the function. –  Jan 07 '10 at 23:26

3 Answers3

1

A list of tab stops specifies particular columns, not distances between stops. That is, if the list is 5,8,10 then a tab in positions 1-4 should place the cursor at 5, in positions 5-7 should place the cursor at 8, and 8-9 place the cursor at 10. After each newline the argument list should start over from the first tab stop again. The behavior on a line after the last defined tab stop is up to you, typically you would go back to some default tab stop interval.

Sparr
  • 7,489
  • 31
  • 48
  • And when i enter newline, then have the arguments go all over again? I mean if the arguments are 5, 8, 10 then do the tabstops as u said. and if at 25st char a newline comes, then go all over again (5, 8, 10)? – Tool Jan 08 '10 at 00:31
0

I'd interpret TABSTOP 5 8 10 to mean there are tab stops at the 5th, 8th, and 10th columns (and after that, every 8 columns, or whatever you're using as the default. It's open to question whether the next tab stop after column 10 should be at column 18 (8 spaces later) or 16 (the next multiple of the default 8).

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111
0

You have some leeway here, as you're designing it; however, the most popular method is to continue with the default width after the last supplied width.

For example, if [5, 8, 10] is supplied and the default is 8, it would continue as [5, 8, 10, 18, 26, 34, ...] or [5, 8, 10, 16, 24, 32, ...], depending on preference.

Note that I'm using these numbers as tab stops, instead of widths. So [5, 8] means the first stop is at 5 with width 5, and the second is at 8 with width 3.