Reputation: 57
Is there a way to find a word within a string in a case insensitive manner?
I would like to find "Word" or "WOrd" or "word" etc... in a C program.
I saw some solutions before posting this question but they don't work anymore or force me to touch the original string to make it all upper cases which is not what I want. Any suggestion to make it?
Upvotes: 4
Views: 1095
Reputation: 144949
If you want to find a word within a string in a case independent manner, there is a library function strcasestr()
on GNU systems. Here is a simple implementation:
#include <ctype.h>
#include <string.h>
char *strcasestr(const char *haystack, const char *needle) {
size_t i;
for (;;) {
for (i = 0;; i++) {
if (needle[i] == '\0')
return (char *)haystack;
if (tolower((unsigned char)haystack[i]) != tolower((unsigned char)needle[i]))
break;
}
if (*haystack++ == '\0')
return NULL;
}
}
Upvotes: 1
Reputation: 5221
It is possible to make it more general using regular expressions with the regex() service. Here is an example program with a function named find_pattern() accepting two parameters: the string into which the search is to be done and a pattern to look for.
#include <stdio.h>
#include <sys/types.h>
#include <regex.h>
#include <libgen.h>
const char *find_pattern(const char *string, const char *pattern)
{
int rc;
regex_t reg;
const char *found = (const char *)0;
regmatch_t match;
rc = regcomp(®, pattern, REG_EXTENDED|REG_NEWLINE);
if (rc != 0) {
fprintf(stderr, "Invalid regex '%s', error %d\n", pattern, rc);
return (const char *)0;
}
rc = regexec(®, string, 1, &match, 0);
if (0 == rc) {
found = string + match.rm_so;
}
regfree(®);
return found;
} // find_pattern
int main(int ac, char *av[])
{
const char *str;
if (ac != 3) {
fprintf(stderr, "Usage: %s string regex\n", basename(av[0]));
return 1;
}
str = find_pattern(av[1], av[2]);
if (str) {
printf("%s\n", str);
return 0;
}
return 1;
} // main
Some tries:
$ gcc search.c -o search
$ ./search "azerty wOrD qwErty" '[wW][Oo][rR][dD]'
wOrD qwErty
$ ./search "azerty word qwErty" '[wW][Oo][rR][dD]'
word qwErty
$ ./search "azerty word qwErty" '[wW][Oo][R][D]'
$ echo $?
1
$ ./search "azerty woRD qwErty" '[wW][Oo][R][D]'
woRD qwErty
Upvotes: -1
Reputation: 154245
Is there a way to compare a string witihn a word with case insensitive?
To compare strings without case sensitivity, fold the values using tolower()
or toupper()
.
#include <ctype.h>
int compare(const char *s1, const char *s2) {
const unsigned char *u1 = (const unsigned char *) s1; // Use unsigned char for use with `to....()`
const unsigned char *u2 = (const unsigned char *) s2;
while (*u1 && toupper(*u1) == toupper(*u2)) {
u1++;
u2++;
}
int ch1 = toupper(*u1);
int ch2 = toupper(*u2);
return (ch1 > ch2) - (ch1 < ch2);
}
To cope with letters outside the common ASCII range which may have a non-one-to-one upper/lower mapping, convert twice:
while (*u1 && tolower(toupper(*u1)) == tolower(toupper(*u2))) {
Using tolower()
or toupper()
or the above in either order makes no difference when looking for equality, but can make an order difference. e.g. Is _
before or after A-Z
?
Upvotes: 1
Reputation: 1573
That's one way to do it
#include <stdio.h>
#include <string.h>
#define SIZE 100
int matchWord( char *s );
int main() {
char s[SIZE];
int i, len, match = 0;
fgets(s, SIZE, stdin);
len = strlen(s);
for(i = 0; i < len - 3; i++) {
if( matchWord(s+i) ) {
match = 1;
break;
}
}
match ? printf("Match found in position %d\n", i) : puts("Not found");
return 0;
}
int matchWord( char *s )
{
static char w[8] = "wordWORD";
int response = 1;
for(int i = 0; i < 4; i++) {
if( s[i] != w[i] && s[i] != w[i+4] ) {
response = 0;
break;
}
}
return response;
}
Upvotes: 0
Reputation: 552
You can make your own function to compare these types of strings. I've implemented it and you can modify it for yourself.
#include <stdio.h>
#include <stdlib.h>
// returns true if X and Y are same
int compare(const char *X, const char *Y)
{
while (*X && *Y)
{
if (abs(*X-*Y)!=32 && *X != *Y) //here 32 is neglecting the case
return 0;
X++;
Y++;
}
return (*Y == '\0');
}
// Function to implement mystrstr() function
const char *mystrstr(const char *X, const char *Y)
{
while (*X != '\0')
{
if ((*X == *Y) && compare(X, Y))
return X;
X++;
}
return NULL;
}
// Implement mystrstr function in C
int main()
{
char *X = "GHOST HUNT - Coding made easy";
char *Y = "CodiNg";
printf("%s\n", mystrstr(X, Y));
return 0;
}
//OUTPUT
Coding made easy
Upvotes: 0