My exercise requires that I can use case-insensitive input. My approch is that I use the tolower and toupper function.
How can I convert the array to lowercase letters?
void KULstrcichr(char *arr, char search)
{
printf("Return value when uppercase character %c is passed to isupper(): %d\n", search, isupper(search));
// The strchr() function returns a pointer to the first occurrence of the character c in the string s.
if (isupper(search))
{
printf("Groß\n");
char lowercasesearch = tolower(search);
printf("Das ist der Output: %s", arr);
char *ptr = strchr(arr, lowercasesearch);
printf("Das ist der Buchstabe: %s", ptr);
}
else
{
printf("Klein\n");
char upercasesearch = toupper(search);
printf("Das ist der Output: %s", arr);
char *ptr = strchr(arr, upercasesearch);
printf("Das ist der Buchstabe: %s", ptr);
}
}
CodePudding user response:
According to the title of the question
Make own strchr() function but case-insensitive
your code does not make any sense. You should write your own function similar to strchr
that is declared in the C Standard like
char * strchr(const char *s, int c);
The function should be declared and defined the following way
char * my_strchr( const char *s, int c )
{
c = tolower( ( unsigned char )c );
while ( *s && tolower( ( unsigned char ) *s ) != c ) s;
return c == '\0' || *s != '\0' ? ( char * )s : NULL;
}
CodePudding user response:
"How can I convert the array to lowercase letters?" - you don't. Instead, check character by character until you've reached the end of the string.
- First convert the
char
you search for to lower (or upper) case.char lowsearch = tolower((unsigned char)search);
- Then loop
arr
until*arr == '\0'
and check each character on the way:for(;*arr != '\0'; arr) { if(tolower((unsigned char)*arr) == lowsearch) return arr; } return NULL;
Note that this requires that you return a char*
just like strchr
, not void
CodePudding user response:
This little assignment is more tricky than it looks:
your code does not always work because you only search either for uppercase or for lowercase, depending on the case of
search
, which does not cover all cases (pun intended).using
strchr
first with uppercase, then with lowercase if uppercase was not found is still incorrect: you must find the first match for either case.you must also find the null terminator if
search
is0
. Simple implementations usually fail this test.tolower
andtoupper
are not defined for negative values different fromEOF
, hence they should not be passedchar
values that can be negative on platforms wherechar
is signed by default. Casting thechar
argument as(unsigned char)
is a simple way to avoid this issue.
Here is an example:
// using int c for compatibility with char *strchr(const char *s, int c)
char *KULstrcichr(const char *s, int c) {
int uc = tolower((unsigned char)c);
for (;; s ) {
if (tolower(*(unsigned char *)s) == uc)
return (char *)s;
if (*s == '\0')
return NULL;
}
}
CodePudding user response:
How can I convert the array to lowercase letters?
void KULstrcichr(char *arr, char search)
To achieve "Make own
strchr()
function but case-insensitive", use an interface likechar *strchr(const char *s, int c);
for maximum compatibility with that standard function.Convert the
search
and*arr
to a common case. e.g.tolower()
.tolower(int ch)
is defined for ach
in theunsigned char
range andEOF
.
Example:
char *TLG_strchr(const char *s, int c) {
c = tolower((unsigned char)c);
// str...() functions perform as if `s` was `unsigned char *`.
const unsigned char *us = (const unsigned char *) s;
while (tolower(*us) != c && *us) {
us ;
}
return tolower(*us) == c ? (char *) us : NULL;
}
Pedantic: (unsigned char)*s
is incorrect for rare non-2's compliment machines with signed char
. Better as *((unsigned char *)s)
, which is effectively what this answer does, to properly access negative char
and distinguish 0 from -0. This likely will be a non-issue for the next version of C as that is expected to require 2's compliment.
CodePudding user response:
Since it looks like you're using simple 8-bit ASCII characters, note that a given uppercase character is just (lowercase & 0x20). Take the input character and run it through strchr() twice: once with a lowercase version, and once with an uppercase version.
char *myStrchr(const char *s, char c) {
char *pLower;
char *pUpper;
char *p;
c |= 0x20;
pLower = strchr(s, c);
c &= ~0x20;
pUpper = strchr(s, c);
if (pLower == NULL) {
p = pUpper;
} else if (pUpper == NULL) {
p = pLower;
} else {
p = (pLower < pUpper) ? pLower : pUpper;
}
return p;
}
Note: I don't think you want your function to be of type void.
EDIT: if your input string may contain characters other than letters, you'll need to bound-check before performing the searches.