【问题标题】:Trying to remove substring from string in C, keep failing试图从C中的字符串中删除子字符串,一直失败
【发布时间】:2019-04-22 05:46:00
【问题描述】:

我知道这个问题已经被问过很多次了,但我根本无法理解我做错了什么。每次我取得一些进展时,我都会收到一个新错误。我使用的代码非常基础,因为我是新手,我们的教授需要使用 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];
        }       
    }
}

我得到的错误是删除函数有冲突的类型。对于修复我的代码的任何帮助将不胜感激,甚至我的问题的替代解决方案也将非常棒。

【问题讨论】:

  • remove 已在 stdio.h 标头中定义。您需要将您的函数重命名为其他名称。
  • 你应该never use gets()。它不对输入进行边界检查。而是使用fgets()
  • 是的,是的,我知道,但不幸的是,按照我的教授的指示,我仅限于此。您的解决方案解决了这个问题,非常感谢您的帮助,但似乎我的代码是错误的。你能帮我弄清楚我哪里出错了吗?
  • 您能否解释一下您的代码应该如何工作,即removeidentify 函数?我很难理解里面的逻辑。
  • identify 函数应该检查用户在单词数组中输入的单词是否与句子数组中的单词相对应。删除函数应该从字符串中删除那个单词,然后我应该打印出没有用户想要删除的单词的新句子数组。

标签: c arrays string substring


【解决方案1】:

正如在 cmets 中确定的那样,由于 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 中的问题留给你作为练习——毕竟这是一项作业。

【讨论】:

  • 你是一个了不起的人,我的朋友,谢谢你帮助我。
  • @sntovas 如果此帖子充分回答了您的问题,请将其标记为已接受,以奖励声誉并随时给它竖起大拇指,以奖励提供答案的人更多的声誉你在寻找。
猜你喜欢
  • 1970-01-01
  • 2011-10-15
  • 2020-10-28
  • 1970-01-01
  • 2019-09-08
  • 1970-01-01
相关资源
最近更新 更多