0

I know this question has been asked many times before but I simply cannot get my head around what I am doing wrong. Everytime I make some progress I get a new error. The code I am using is really basic because I am a newbie and our professor requires the usage of scanf and gets. This is my code so far:

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

The error I am getting, is that the remove function has conflicting types. Any help with fixing my code will be greatly appreciated, or even an alternative solution to my problem would bre great.

Govind Parmar
  • 20,656
  • 7
  • 53
  • 85
sntovas
  • 27
  • 4
  • 1
    `remove` is already defined in the `stdio.h` header. You need to rename your function to something else. – apilat Nov 19 '18 at 20:11
  • You should [never use `gets()`](https://stackoverflow.com/questions/1694036/why-is-the-gets-function-so-dangerous-that-it-should-not-be-used). It doesn't do bounds checking on the input. Instead use `fgets()`. – apilat Nov 19 '18 at 20:13
  • Yes, yes, I know but unfortunately I am limited to it as per my proffesors instructions. Your solution solved that problem, and I thank you very much for your help, but it seems my code is wrong. Could you maybe help me figure out where I went wrong? – sntovas Nov 19 '18 at 20:21
  • Could you explain how your code is _supposed_ to work, i.e. the `remove` and `identify` functions? I'm struggling to understand the logic inside. – apilat Nov 19 '18 at 20:23
  • The identify function is supposed to check if the word that is inputed by the user in the word array corresponds to a word in the sentence array. The remove function should remove that word from the string, and then I am supposed to print out the new sentence array without the word that the user wants to remove. – sntovas Nov 19 '18 at 20:28
  • Your `else (condition)` should be `else if (condition)` and should not call `scan` again – stark Nov 19 '18 at 20:54

1 Answers1

1

As established in the comments, the compiler error is generated because remove is already defined in the stdio.h. After changing, the name the code compiles successfully, but still doesn't work as expected.

identify is the function which is meant to find whether a substring exists in a string and return its position. This is very similar to how strstr from the standard library works - I'd suggest having a look at an implementation of that function, to better understand how this is done. The function you implemented only correctly finds substrings of length 1, at the end of the string. I have highlighted errors in the code below which cause this.

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 is inefficient due to the nested loops and the range of characters copied needs to be shortened - right now data is access beyond the end of the array.

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

I will leave the problems in main as an exercise to you - this is an assignment after all.

apilat
  • 1,370
  • 8
  • 17
  • You are an amazing person my friend, thank you for helping me. – sntovas Nov 19 '18 at 21:14
  • @sntovas if this posted sufficiently answered your question please mark it as accepted to reward the answer with reputation and also feel free to give it a thumbs up to reward even more reputation to the person who supplied the answer you were seeking. – Bwebb Nov 19 '18 at 21:43