Почему не работает эта версия функции strstr () без учета регистра? - PullRequest
0 голосов
/ 06 июня 2019

В попытке решить проблему из учебника я пытаюсь создать версию функции strstr() без учета регистра, которая написана на языке Си.Пока что я столкнулся с двумя проблемами.Первая проблема заключалась в том, что когда я делал регистронезависимую версию strstr(), она работала, но не остановилась на первой совпадающей строке и продолжала возвращать строку, даже если они не совпадали.

strstr() должен увидеть первый экземпляр совпадающего символа до указанного числа n и затем остановиться.Как если бы я написал: "Xehanort" в строке A и "Xemnas" в строке B и указал 4, в качестве number он вернул бы Xe.

Идея, лежащая в основе версии без учета регистра, заключается в том, что я могу написать: "Xehanort" в одной строке и "xemnas" в следующей строке и вернуть ее Xe.

Однако яЯ столкнулся с новой проблемой в новом коде, который я пробовал: похоже, функция вообще не хочет запускаться.Я проверил это, и оказалось, что функция, кажется, находится в аварийном состоянии, и я не уверен, как заставить это остановиться.

Я пытался редактировать код, я пытался использовать разные циклы for, но решил, что код пока не должен быть слишком сложным, я также пробовал совершенно другой код, чем вы собираетесьчитать, но это привело к проблеме, упомянутой ранее.

#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;
}

Код, который вы увидите, запросит строки, которые вы хотите ввести.В идеале он должен возвращать ввод.

Затем он должен выполнить функцию stristr и вернуть первый экземпляр совпадающей строки с учетом регистра.

Однако созданная мной функция, похоже, даже не запускается.

Ответы [ 2 ]

1 голос
/ 09 июня 2019

Ваш код имеет неопределенное поведение (в этом случае вызывает ошибку сегментации), потому что вы пытаетесь сохранить результирующую строку через неинициализированный указатель str3.

Стандартная функция strstr возвращает указатель на соответствующую подпоследовательность, вы должны сделать то же самое. Третий аргумент бесполезен, если первый и второй аргументы являются собственными строками Си.

Вот модифицированная версия:

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;
    }
}

Примечания:

  • function 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';
        ...
    }
    
1 голос
/ 07 июня 2019

Третья строка может быть передана в функцию и заполнить эту строку соответствующими символами.
Использовать 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
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...