I'm currently writing code in C, which selects symbols and numbers from whole ASCII-available characters. As a beginner of programmer, I usually did
if ((i > 25 && i < 50) || (i > 100 && i < 200)) { contents }
for the variable i
being between 25~50, 100~200 (exclusive) to fit the condition.
If I want to set multiple ranges like 32~64(! to @
) and 91~96([ to `
) and 123~126({ to ~
) then would there be any better (meaning shorter or simpler code) or should I stick with this method, keep adding each range as in the code above?
If x is in range, then it must be greater than or equal to low, i.e., (x-low) >= 0. And must be smaller than or equal to high i.e., (high – x) <= 0. So if result of the multiplication is less than or equal to 0, then x is in range.
For your specific case, the <ctype.h>
collection of functions would do
if (isprint(i) && !isalpha(i))
Added bonus: It even works on non-ascii systems.
You can write a function that checks if the value belongs to any of given ranges:
struct Range {
int min;
int max;
};
bool in_ranges(int character, struct Range *ranges, size_t num_ranges) {
for(size_t i = 0; i < num_ranges; ++i) {
if(ranges[i].min < character && character < ranges[i].max)
return true;
}
return false;
}
int main() {
struct Range rngs[] = {{25,50}, {100,200}};
bool at_sign_si_in_range = in_ranges('@', rngs, 2);
return 0;
}
It makes editing ranges much simpler and improves readability. Also, if you continue to write all ranges in conditional clause as in your example, consider checking ranges like
lower_bound < value && value < upper_bound
It looks like mathematical notation (x < a < y
) and also seems easier to read.
If you are using single byte characters, you may be able to get better performance using an array of flags, setting either individual bits or whole bytes to indicate character values that are in one of the ranges.
If you are writing code for an Intel processor that supports the SSE 4.2 instructions, you might want consider using PCMPISTRI or similar, which can compare up to 16 single byte characters against up to 8 different ranges in a single instruction.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With