I have a function that should be passed a string with two numbers (as a regex: /-?[0-9]+ -?[0-9]+/) and return the second.
I’ve decided that the program should do error checking. First, it should test if the string is actually of the desired form; second, it should ensure that the first numbers (the ones that are not returned) are sequential.
Now I’ve been programming for a long time and this is not a difficult task. (It’s made slightly more difficult by the fact that the numbers need not fit into a machine word.) But my question is about how I should do this rather than how I can. All of the solutions I’ve come up with are somewhat ugly.
- I could use a global variable to keep the values in and compare them (or just leave the value there if it’s
NULL); this seems like The Wrong Thing. - I could pass one or both of the return value and the last/current line’s first number by reference and modify them
- I could use the return value to give a bool for there was/was not an error
- etc.
So any thoughts relating to the proper way to deal with error-checking of this sort in C would be welcome.
This is related to a much more theoretical question I asked on cstheory. For reference, here is the function:
char*
scanInput(char* line)
{
int start = 0;
while (line[start] == ' ' || line[start] == '\t')
start++;
if (line[start] == '#')
return NULL; // Comment
if (line[start] == '-')
start++;
while (line[start] >= '0' && line[start] <= '9')
start++;
while (line[start] == ' ' || line[start] == '\t')
start++;
int end = start;
if (line[end] == '-')
end++;
while (line[end] >= '0' && line[end] <= '9')
end++;
if (start == end)
return NULL; // Blank line, or no numbers found
line[end] = '\0';
return line + start;
}
and it is called like so:
while(fgets(line, MAX_LINELEN, f) != NULL) {
if (strlen(line) > MAX_LINELEN - 5)
throw_error(talker, "Maximum line length exceeded; file probably not valid");
char* kept = scanInput(line);
if (kept == NULL)
continue;
BIGNUM value = strtobignum(kept);
if (++i > MAX_VECLEN) {
warning("only %d terms used; file has unread terms", MAX_VECLEN);
break;
}
// values are used here
}
Ultimately, you are going to need to isolate and convert both big numbers in each line. To check that the first number on the line is the one that follows the previous, you will have to keep a record of the last such number found. So, you will probably need a structure such as:
The
are_consecutive()function determines whether its second argument is one greater than its first. Theprocess()function does whatever you need to do with the second value. TheScanDoubleBigNum()function is related to yourScanInput()but it reads two values. The actual code will call another function (call itScanBigNum()) containing about half ofScanInput()(since that contains essentially the same code twice), plus the conversion that currently occurs in your loop. The code inScanDoubleBigNum()will callScanBigNum()twice. Note thatScanBigNum()will need to identify where the scan finishes so that the second call can continue where the first stopped.I’m taking the liberty of assuming that a
BIGNUMis an allocated structure identified by a pointer, so the initializationBIGNUM old_value = 0;is a way of indicating there is no value yet. There is presumably a function to release aBIGNUM. If this is incorrect, then you need to adapt the proposed code to accommodate the actual behaviour of theBIGNUMtype. (Is this based on OpenSSL or SSLeay code?)