制作自己的 strchr() 函数但不区分大小写
Make own strchr() function but case-insensitive
我的练习要求我可以使用不区分大小写的输入。我的做法是使用tolower和toupper函数。
如何将数组转换为小写字母?
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);
}
}
根据题名
Make own strchr() function but case-insensitive
你的代码没有任何意义。您应该编写自己的类似于 strchr
的函数,该函数在 C 标准中声明为
char * strchr(const char *s, int c);
该函数应按以下方式声明和定义
char * my_strchr( const char *s, int c )
{
c = tolower( ( unsigned char )c );
while ( *s && tolower( ( unsigned char ) *s ) != c ) ++s;
return c == '[=11=]' || *s != '[=11=]' ? ( char * )s : NULL;
}
这是一个演示程序。
#include <stdio.h>
#include <ctype.h>
char *my_strchr( const char *s, int c )
{
c = tolower( ( unsigned char )c );
while (*s && tolower( ( unsigned char )*s ) != c) ++s;
return c == '[=12=]' || *s != '[=12=]' ? ( char * )s : NULL;
}
int main( void )
{
char s[] = "Hello";
char *p = my_strchr( s, 'h' );
if (p != NULL)
{
printf( "position = %td, substring = %s\n", p - s, s );
}
}
程序输出为
position = 0, substring = Hello
因为看起来您使用的是简单的 8 位 ASCII 字符,请注意给定的大写字符只是 (lowercase & 0x20)。获取输入字符并 运行 通过 strchr() 两次:一次是小写版本,一次是大写版本。
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;
}
注意:我认为您不希望您的函数是 void 类型。
编辑:如果您的输入字符串可能包含字母以外的字符,您需要在执行搜索之前bound-check。
“如何将数组转换为小写字母?” - 你不会。相反,一个字符一个字符地检查,直到到达字符串的末尾。
- 首先将您搜索的
char
转换为小写(或大写)。
char lowsearch = tolower((unsigned char)search);
- 然后循环
arr
直到 *arr == '[=14=]'
并检查途中的每个字符:
for(;*arr != '[=11=]'; ++arr) {
if(tolower((unsigned char)*arr) == lowsearch) return arr;
}
return NULL;
请注意,这需要您 return 一个 char*
就像 strchr
,而不是 void
How can I convert the array to lowercase letters? void KULstrcichr(char *arr, char search)
要实现“制作自己的 strchr()
函数但 case-insensitive”,请使用 char *strchr(const char *s, int c);
之类的接口以最大程度地兼容该标准函数。
将search
和*arr
转换为普通情况。例如tolower()
。 tolower(int ch)
是为 unsigned char
范围内的 ch
和 EOF
.
定义的
示例:
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;
}
迂腐:(unsigned char)*s
对于罕见的非 2 的带有 签名 char
的恭维机器是不正确的。更好的是 *((unsigned char *)s)
,这实际上是这个答案所做的,以正确访问否定 char
并将 +0 与 -0 区分开来。这可能是下一个 C 版本的 non-issue,因为预计需要 2 的赞美。
这个小任务比看起来更棘手:
您的代码并不总是有效,因为您只搜索大写或小写,具体取决于 search
的大小写,这并不涵盖所有情况(双关语意)。
首先使用大写字母 strchr
,如果未找到大写字母,则使用小写字母仍然不正确:您必须找到任何一种情况下的第一个匹配项。
如果 search
是 0
,您还必须找到空终止符。简单的实现通常无法通过此测试。
tolower
和 toupper
没有为不同于 EOF
的负值定义,因此它们不应被传递 char
值在默认签署 char
的平台上为负值。将 char
参数转换为 (unsigned char)
是避免此问题的简单方法。
这是一个例子:
// 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 == '[=10=]')
return NULL;
}
}
我的练习要求我可以使用不区分大小写的输入。我的做法是使用tolower和toupper函数。
如何将数组转换为小写字母?
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);
}
}
根据题名
Make own strchr() function but case-insensitive
你的代码没有任何意义。您应该编写自己的类似于 strchr
的函数,该函数在 C 标准中声明为
char * strchr(const char *s, int c);
该函数应按以下方式声明和定义
char * my_strchr( const char *s, int c )
{
c = tolower( ( unsigned char )c );
while ( *s && tolower( ( unsigned char ) *s ) != c ) ++s;
return c == '[=11=]' || *s != '[=11=]' ? ( char * )s : NULL;
}
这是一个演示程序。
#include <stdio.h>
#include <ctype.h>
char *my_strchr( const char *s, int c )
{
c = tolower( ( unsigned char )c );
while (*s && tolower( ( unsigned char )*s ) != c) ++s;
return c == '[=12=]' || *s != '[=12=]' ? ( char * )s : NULL;
}
int main( void )
{
char s[] = "Hello";
char *p = my_strchr( s, 'h' );
if (p != NULL)
{
printf( "position = %td, substring = %s\n", p - s, s );
}
}
程序输出为
position = 0, substring = Hello
因为看起来您使用的是简单的 8 位 ASCII 字符,请注意给定的大写字符只是 (lowercase & 0x20)。获取输入字符并 运行 通过 strchr() 两次:一次是小写版本,一次是大写版本。
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;
}
注意:我认为您不希望您的函数是 void 类型。
编辑:如果您的输入字符串可能包含字母以外的字符,您需要在执行搜索之前bound-check。
“如何将数组转换为小写字母?” - 你不会。相反,一个字符一个字符地检查,直到到达字符串的末尾。
- 首先将您搜索的
char
转换为小写(或大写)。char lowsearch = tolower((unsigned char)search);
- 然后循环
arr
直到*arr == '[=14=]'
并检查途中的每个字符:for(;*arr != '[=11=]'; ++arr) { if(tolower((unsigned char)*arr) == lowsearch) return arr; } return NULL;
请注意,这需要您 return 一个 char*
就像 strchr
,而不是 void
How can I convert the array to lowercase letters?
void KULstrcichr(char *arr, char search)
要实现“制作自己的
strchr()
函数但 case-insensitive”,请使用char *strchr(const char *s, int c);
之类的接口以最大程度地兼容该标准函数。将
定义的search
和*arr
转换为普通情况。例如tolower()
。tolower(int ch)
是为unsigned char
范围内的ch
和EOF
.
示例:
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;
}
迂腐:(unsigned char)*s
对于罕见的非 2 的带有 签名 char
的恭维机器是不正确的。更好的是 *((unsigned char *)s)
,这实际上是这个答案所做的,以正确访问否定 char
并将 +0 与 -0 区分开来。这可能是下一个 C 版本的 non-issue,因为预计需要 2 的赞美。
这个小任务比看起来更棘手:
您的代码并不总是有效,因为您只搜索大写或小写,具体取决于
search
的大小写,这并不涵盖所有情况(双关语意)。首先使用大写字母
strchr
,如果未找到大写字母,则使用小写字母仍然不正确:您必须找到任何一种情况下的第一个匹配项。如果
search
是0
,您还必须找到空终止符。简单的实现通常无法通过此测试。tolower
和toupper
没有为不同于EOF
的负值定义,因此它们不应被传递char
值在默认签署char
的平台上为负值。将char
参数转换为(unsigned char)
是避免此问题的简单方法。
这是一个例子:
// 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 == '[=10=]')
return NULL;
}
}