为解决教科书问题,我正在尝试创建名为C strstr()
的函数的不区分大小写的版本。到目前为止,我遇到了两个问题。第一个问题是,当我制作strstr()
的不区分大小写的版本时,它可以工作,但它并没有在第一个匹配的字符串处停止,并且即使它们不匹配也继续返回该字符串。
strstr()
应该看到匹配字符的第一个实例,最多指定n个计数,然后停止。就像我写的那样:字符串"Xehanort"
中的A
和字符串"Xemnas"
中的B
并指定4
作为number
,它将返回{ {1}}。
不区分大小写的版本的想法是,我可以在一个字符串中写成Xe
,在下一个字符串中写成"Xehanort"
,并使它返回"xemnas"
。
但是,我在尝试的新代码中遇到了一个新问题:该函数似乎根本不想运行。我已经对此进行了测试,结果表明该功能似乎崩溃了,我不确定如何使其停止。
我尝试过编辑代码,尝试过使用不同的for循环,但是发现代码并不需要太复杂,我还尝试了完全不同于您要阅读的代码,但这导致了前面提到的问题。
Xe
您看到的代码将询问您要输入的字符串。理想情况下,它应该返回输入。
然后它应该执行#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#define MAX 100
char *stristr4(const char *p1, const char *p2, size_t num);
int main() {
char c[MAX], d[MAX];
printf("Please enter the string you want to compare.");
gets(c);
printf("Please enter the next string you want to compare.");
gets(d);
printf("The first string to be obtained from \n%s, and \n%s is \n%s",
c, d, stristr4(c, d, MAX));
}
char *stristr4(const char *p1, const char *p2, size_t num) {
const char *str1 = p1;
const char *str2 = p2;
char *str3;
int counter = 0;
for (int i = 0; i < num; i++) {
for (int j = 0; j < num; j++) {
if (tolower(str1[i]) == tolower(str2[j])) {
str3[i] = str1[i];
counter++;
} else {
if (counter > 0) {
break;
} else
continue;
}
}
}
return str3;
}
函数,并返回不区分大小写的匹配字符串的第一个实例。
但是,我创建的功能似乎甚至没有运行。
答案 0 :(得分:1)
第三个字符串可以传递给函数,并用匹配的字符填充该字符串。
使用fgets
代替gets
。
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#define MAX 100
int stristr4(const char* p1, const char *p2, char *same);
int main( void)
{
int comp = 0;
char c[MAX] = "", d[MAX] = "", match[MAX] = "";//initialize to all zero
printf ( "Please enter the string you want to compare. ");
fflush ( stdout);//printf has no newline so make sure it prints
fgets ( c, MAX, stdin);
c[strcspn ( c, "\n")] = 0;//remove newline
printf ( "Please enter the next string you want to compare. ");
fflush ( stdout);//printf has no newline so make sure it prints
fgets ( d, MAX, stdin);
d[strcspn ( d, "\n")] = 0;//remove newline
comp = stristr4 ( c, d, match);
printf ( "Comparison of \n%s, and \n%s is \n%d\n", c, d, comp);
if ( *match) {
printf ( "The matching string to be obtained from \n%s, and \n%s is \n%s\n"
, c, d, match);
}
return 0;
}
int stristr4 ( const char *p1,const char *p2, char *same)
{
//pointers not pointing to zero and tolower values are equal
while ( *p1 && *p2 && tolower ( (unsigned char)*p1) == tolower ( (unsigned char)*p2))
{
*same = tolower ( (unsigned char)*p1);//count same characters
same++;//increment to next character
*same = 0;//zero terminate
p1++;
p2++;
}
return *p1 - *p2;//return difference
}
答案 1 :(得分:1)
您的代码具有未定义的行为(在这种情况下会导致分段错误),因为您尝试通过未初始化的指针str3
存储结果字符串。
标准函数strstr
返回指向匹配子序列的指针,您应该执行相同的操作。如果第一个和第二个参数是正确的C字符串,则第三个参数将无用。
这是修改后的版本:
char *stristr4(const char *p1, const char *p2) {
for (;; p1++) {
for (size_t i = 0;; i++) {
if (p2[i] == '\0')
return (char *)p1;
if (tolower((unsigned char)p1[i]) != tolower((unsigned char)p2[i]))
break;
}
if (*p1 == '\0')
return NULL;
}
}
注意:
tolower()
与<ctype.h>
中的其他函数一样,采用的int
必须具有unsigned char
的值或特殊的负值EOF
。必须将char
参数转换为unsigned char
,以避免对char
负值的不确定行为。默认情况下,char
可以签名或不签名,具体取决于平台和编译器设置。
您不应从不 gets()
。该功能已过时,无法在不受控制的输入下安全使用。使用fgets()
并删除结尾的换行符:
if (fgets(c, sizeof c, stdin)) {
c[strcspn(c, "\n")] = '\0';
...
}