The general idea is to parse the numbers and store them somewhere, the code I gave was just an example (written in C++, it's not that hard to convert it to C). For example, if you would do the same with a dynamic array in C, you would probably do something like this:
1 2 3 4 5 6 7 8 9 10 11
|
//First we allocate memory for the command line parameters
size_t numtabs = (argc-1);
int* tabstops = (int*)malloc(numtabs * sizeof(int));
//Next we loop through all arguments
for(int i = 1; i < argc; ++i)
{
//Convert the char* argument to an integer
int location = atoi(argv[i]);
//Then we store it in the array
tabstops[i - 1] = location;
}
|
And your function would become something like this:
1 2 3 4 5 6 7 8 9 10 11 12
|
//We'll need an arraysize parameter since C arrays won't store this for us
int countspaces(int* tabstops, size_t arraysize, int offset)
{
//Get the upper bound
int* pos = get_upper_bound(tabstops,tabstops+arraysize,offset);
//Set the default tab width
int tabstop = DEFAULT_TAB;
//Check if there was a position in the array
if(pos != NULL)
tabstop = *pos; //Set it to the found tabstop
return tabstop - (offset % tabstop); //Return the number of spaces
}
|
Since C doesn't come with any sort of get_upper_bound function, we'll have to write it ourselves. Luckily this site comes with a reference which shows us what it does (and even an implementation of the code, but since we like to reinvent the wheel, let's do it ourselves).
std::upper_bound (located in the <algorithm> header) is a function that retrieves the first element in a container (or actually, an iterator range) is greater than the value specified. While the C++ standard library comes with a much better implementation (guaranteed to be log
2(N)+1), ours will be linear, since that's just a simple loop.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
//Returns the first value greater than val, between first (inclusive) and last (exclusive)
int* get_upper_bound(int* first, int* last, int val)
{
while(first != last)
{
//Check if this value is greater than the specified one
if(*first > val)
return first; //If so, we found our answer
//Otherwise we'll go to the next element
++first;
}
//If we make it here we couldn't find the value, so return an error
//We'll use NULL here, although the C++ version returns last
return NULL;
}
|
Of course, this code can be heavily optimized (see
http://www.cplusplus.com/reference/algorithm/upper_bound/ for an idea). And this code isn't completely compatible with what the C++ standard says about upper_bound, for example we use the > operator while the standard says we should use the < operator (of course you could change the comparison to !(val < *first) and you've solved that problem). But since we're not implementing the C++ standard library here and only using int, I say we can get away with using this.
And now you can call this new function (written in nothing more than plain C, actually if you write atoi and malloc yourself you don't even have to rely on the C standard library) like this:
|
int numSpaces = countspaces(tabstops,numtabs,pos);
|
It's actually been a while since I last relied on pure C to do everything. Are your programming for some sort of embedded system or so?