为什么这个不区分大小写的strstr()函数不能正常工作?

时间:2019-06-06 12:35:38

标签: c string

为解决教科书问题,我正在尝试创建名为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; } 函数,并返回不区分大小写的匹配字符串的第一个实例。

但是,我创建的功能似乎甚至没有运行。

2 个答案:

答案 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';
        ...
    }