Searching in char*

S

santosh

spl said:
What is the best way to check any ASCII characters between 33 to 47
exists in a char*?

For maximal portability use the ispunct() function. Otherwise use
something like:

if (ch >= 33 && ch <= 47) /* ... */

This is of course specific to ASCII encoding. Using ispunct may be
better but that might return true for punctuation other than those
within ASCII 33 to 47, in which case you have perform further checks.

Another possibility is a switch statement:

switch (ch) {
case '!':
case '"':
case '#':
/* and so on */
default:
/* not matching */
}
 
E

Eric Sosman

spl said:
What is the best way to check any ASCII characters between 33 to 47
exists in a char*?

Here's one way:

#include <string.h>
...
char *s = ...;
if (s[strcspn(s,"\041\042\043\044\045\046\047"
"\050\051\052\053\054\055\056\057"]) {
/* desired characters are present */
}
else {
/* desired characters are absent */
}

Whether this is "best" is for you to decide, not me.
 
S

santosh

santosh said:
For maximal portability use the ispunct() function. Otherwise use
something like:

if (ch >= 33 && ch <= 47) /* ... */

Oops. Didn't catch the char * bit. Use something like:

bool isASCIIpunct(const char *restrict str) {
bool rc = false;
while (*str++) {
if (*str >= 33 && *str <= 47) {
rc = true;
break;
}
}
return rc;
}

<snip>
 
S

spl

No, this is fine only, if I search a single character, but mine is 256
character string, in that I have to find any occurance of the Ascii
characters btw 34 to 47.
 
S

santosh

spl said:
No, this is fine only, if I search a single character, but mine is 256
character string, in that I have to find any occurance of the Ascii
characters btw 34 to 47.

Use a loop. See my other post.
 
M

Mark Bluemel

spl said:
No, this is fine only, if I search a single character, but mine is 256
character string, in that I have to find any occurance of the Ascii
characters btw 34 to 47.

Insufficiently specified... Do you need simply to determine whether
at least one character in the range is present, or identify all
instances of characters in that range?

Either way, it's hardly a challenging task, and as far as I can see,
there's little benefit in trying to use any standard functions.
 
S

spl

Insufficiently specified... Do you need simply to determine whether
at least one character in the range is present, or identify all
instances of characters in that range?

at least one character in the range is present...

I feel Santosh solution would be fine... but if the string goes very
lengthy, let us say more than 1000 character, then loop will go for
1000 time. So performance vice it will be slow?
 
S

santosh

spl said:
at least one character in the range is present...

I feel Santosh solution would be fine... but if the string goes very
lengthy, let us say more than 1000 character, then loop will go for
1000 time. So performance vice it will be slow?

Given a string there is no way other than a linear search for this
problem. I think you'll find performance to be acceptable unless the
strings are *really* large, like say dozens of megabytes. If your
string *is* really that large then it may indicate that you may need to
rethink your data structures to avoid this problem in the first place.

Also I should point out that the solution I presented involving a switch
statement does not meet your stated requirements.
 
M

Morris Dovey

spl said:
I feel Santosh solution would be fine... but if the string goes very
lengthy, let us say more than 1000 character, then loop will go for
1000 time. So performance vice it will be slow?

Probably. The search could also be done using strchr(), which
/might/ result in a faster search depending on compiler
optimization and/or machine architecture - on the other hand a
really smart compiler might be able to arrive at those same
optimizations by examining the loop code...
 
M

Mark Bluemel

spl said:
at least one character in the range is present...

I feel Santosh solution would be fine... but if the string goes very
lengthy, let us say more than 1000 character, then loop will go for
1000 time. So performance vice it will be slow?

There is no alternative to a linear search in this context. One way or
another, each character in the array will need to be examined until you
either find one of your candidates or you reach the end.

As Morris suggests, it's possible that in some contexts the str***()
functions may have been implemented using some neat platform-specific
functionality that will make them quicker than a hand-coded loop, but
generally, I'd suggest that you just take the simple approach.
 
S

santosh

Morris said:
Probably. The search could also be done using strchr(), which
/might/ result in a faster search depending on compiler
optimization and/or machine architecture - on the other hand a
really smart compiler might be able to arrive at those same
optimizations by examining the loop code...

Actually strcspn() or strpbrk() would be more suitable for OP's stated
requirements except for the fact that he wants to restrict the search
to ASCII characters from 33 to 47. A manual loop seems the best
solution to me.
 
J

John Bode

What is the best way to check any ASCII characters between 33 to 47
exists in a char*?

#include <string.h>

int checkFor33to47(const char *str)
{
char set[] = {33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 0};

char *result = strpbrk(str, set);
return result != NULL;
}
 
M

maclab2

#include said:
int checkFor33to47(const char *str)
{
char set[] = {33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 0};

char *result = strpbrk(str, set);
return result != NULL;
}

Maybe faster is to use a Look-Up-Table:

....
char const LUT_33TO47 [] =
{
0 /* 0*/,
0 /* 1*/,
0 /* 2*/,
...
0 /* 32*/,
1 /* 33*/,
1 /* 34*/,
...
1 /* 46*/,
1 /* 47*/,
0 /* 48*/,
...
0 /*255*/
};
....
if (LUT_33TO47[(unsigned int)c])
printf("Ok, character %d is between 33 and 47\n", c);
else
printf("No, character %d is _NOT_ between 33 and 47\n", c);
....

Regards
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,260
Messages
2,571,038
Members
48,768
Latest member
first4landlord

Latest Threads

Top