Пытаясь удалить подстроку из строки в C, продолжайте сбой - PullRequest
0 голосов
/ 19 ноября 2018

Я знаю, что этот вопрос задавался много раз прежде, но я просто не могу понять, что я делаю неправильно.Каждый раз, когда я делаю успехи, я получаю новую ошибку.Код, который я использую, действительно простой, потому что я новичок, а наш профессор требует использования scanf и gets.Это мой код:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 100
int identify(char[], char[]);
int remove(char[], char[], int);
int scan(choice)
{
    while(choice < 0 || choice > 7)
    {
        printf("Invalid input, choose again\n");    
        scanf("%d", &choice);
    }
    return choice;  
}


int main()
{
    char sentence[MAX_SIZE], word[MAX_SIZE];
    int choice, i, j, k, deikths;

    printf("Choose one of the following:\n");
    printf("1. Give sentence\n");
    printf("2. Subtract a word\n");
    printf("3. Add a word\n");
    printf("4. Count the words\n");
    printf("5. Count the sentences\n");
    printf("6. Count the characters\n");
    printf("7. Is the phrase a palindrome?\n");
    printf("0. Exit\n");
    scanf("%d", &choice);
    if(scan(choice) == 1)
    {
        printf("Give sentence:\n");
        gets(sentence);
        gets(sentence);
        printf("%s\n", sentence);
    }
    else(scan(choice) == 2);
    {
        printf("Give word you want to subtract\n");
        gets(word); 
        printf("%s", word);
        deikths = identify(sentence, word);
        if(deikths != -1)
        {
            remove(sentence, word, deikths);
            printf("Sentence without word: %s\n", sentence);
        } 
        else
        {
            printf("Word not found in sentence.\n");
        }
    }
}

int identify(char sentence[], char word[])
{
    int i, j, k;
    for(k = 0; word[k] != '\0'; k++);
    {
        for(i = 0, j = 0; sentence[i] != '\0'; i++)
        {
            if(sentence[i] == word[j])
            {
                j++;
            }
            else
            {
                j = 0;
            }
        }
    }
    if(j == 1)
    {
        return(i - j);
    }
    else
    {
        return -1;
    }
}

int remove(char sentence[], char word[], int deikths)
{
    int i, k;
    for(k = 0; word[k] != '\0'; k++)
    {
        for(i = deikths; sentence[i] != '\0'; i++)
        {
            sentence[i] = sentence[i + k + 1];
        }       
    }
}

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

1 Ответ

0 голосов
/ 20 ноября 2018

Как установлено в комментариях, ошибка компилятора генерируется, потому что remove уже определено в stdio.h.После изменения имени код успешно компилируется, но все равно не работает должным образом.

identify - это функция, предназначенная для определения наличия подстроки в строке и возврата ее позиции.Это очень похоже на то, как работает strstr из стандартной библиотеки - я бы посоветовал взглянуть на реализацию этой функции, чтобы лучше понять, как это делается.Функция, которую вы реализовали только правильно, находит подстроки длиной 1 в конце строки.Я выделил ошибки в приведенном ниже коде, которые вызывают это.

int identify(char sentence[], char word[])
{
    int i, j, k;
    for(k = 0; word[k] != '\0'; k++); // <- this loops is never actually ran because of the trailing semicolon - this is however a good thing as it is redundant
    {
        for(i = 0, j = 0; sentence[i] != '\0'; i++)
        {
            if(sentence[i] == word[j])
            {
                j++;
            }
            else
            {
                j = 0; // <- this makes it so only matches at the end can be found - otherwise, j is just reset back to 0
            }
        }
    }
    if(j == 1) // <- this makes it so only matches of length 1 can be found
    {
        return(i - j); // <- this is only correct if the match is at the end of the sentence
    }
    else
    {
        return -1;
    }
}

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

int strremove(char sentence[], char word[], int deikths)
{
    int i, k;
    for(k = 0; word[k] != '\0'; k++) // <- this loop is redundant
    {
        for(i = deikths; sentence[i] != '\0'; i++) // <- you need to add range checking to make sure sentence[i+k+1] doesn't go beyond the end of the string
        {
            sentence[i] = sentence[i + k + 1];
        }       
    }
}

Я оставлю проблемы в main как упражнение для вас - это задание в конце концов.

...