我需要创建一个函数来删除链表的元素(列表的元素是单词(,其中包含用户输入的字母。基本上,我有一个包含随机单词的.txt文件,将单词加载到链表中后,我需要制作几个函数(这篇文章仅专用于菜单中的第 4 个函数(,其中一个是我遇到麻烦的功能。
我的想法是创建一个单独的函数,如果单词包含字母,它将发送 1,如果不包含字母,则发送 0,然后我创建了一个通过我的链表的函数,并使用第一个函数检查列表中的该元素是否包含该单词,如果包含,那么我将其删除并移动到下一个元素。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Element Element;
struct Element
{
char word[50];
Element *next;
};
Element *load_file(Element *head)
{
char file[500];
scanf("%s", file);
Element *temp = head;
FILE* fp = fopen(file, "r");
if(fp == NULL)
{
printf("Error while loading file.");
return 0;
}
while(!feof(fp))
{
Element *newE = (Element*)malloc(sizeof(Element));
fscanf(fp, "%s", newE->word);
newE->next = NULL;
if(!temp)
{
head = temp = newE;
}
else
{
temp->next = newE;
temp = newE;
}
}
fclose(fp);
printf("nFile loaded successfullyn");
return head;
}
int frequency(Element *head, char *word)
{
Element *temp = head;
int counter = 0;
while(temp != NULL)
{
if(strcmp(temp->word, word) == 0)
{
counter++;
}
temp = temp->next;
}
return counter;
}
int contains(char word[], char letter)
{
int end = strlen(word);
int flag = 0;
for(int i = 0; i < end-1; i++)
{
if(letter == word[i])
{
flag = 1;
break;
}
}
return flag;
}
Element *delete_word(Element *head, char letter)
{
Element *temp = head;
Element *before = NULL;
Element *newHead = head;
while(temp != NULL)
{
if(contains(temp->word, letter))
{
if(before == NULL)
{
newHead = temp->next;
free(temp);
temp = newHead;
}
else
{
before->next = temp->next;
free(temp);
temp = before->next;
}
}
else
{
before = temp;
temp = temp->next;
}
}
return newHead;
}
void printElement(Element *element)
{
printf("%s n", element->word);
}
void printList(Element *head)
{
Element *temp = head;
while(temp != NULL)
{
printElement(temp);
temp = temp->next;
}
}
void meni()
{
printf("************** MENI **************n");
printf("1. Loading text from file n");
printf("2. Print all elements of the list n");
printf("3. Frequency of a certain word n");
printf("4. Delete words that contain a letter n");
printf("5. Load the list into a file n");
printf("6. Exit nn");
}
int main()
{
Element *head = NULL;
int option;
while(1)
{
meni();
scanf("%d", &option);
switch(option)
{
case 1:
{
printf("Input a name of the file: n");
head = load_file(head);
break;
}
case 2:
{
printList(head);
break;
}
case 3:
{
char word[100];
printf("Input a word: ");
scanf("%s", word);
int num = frequency(head, word);
printf("%dn", num);
break;
}
case 4:
{
char word[100];
printf("Input a word: ");
scanf("%s", word);
head = delete_word(head, word);
printList(head);
break;
}
case 5:
{
}
case 6:
{
return 0;
}
}
}
return 0;
}
出于某种原因,它不会对列表进行任何更改。
您的delete_word()
函数声明为:
Element *delete_word(Element *head, char letter);
但是你用char*
来称呼它:
char word[100];
head = delete_word(head, word);
菜单选项显示Delete words that contain a letter
但是当用户选择该选项时,他/她会被指示Input a word:
(混淆(。
然后,将word
中第一个char
的地址发送到函数。从该地址中选择一个char
。它充其量是随机的,它很可能会损坏堆栈(因为您仅通过选择一个char
,可能会从 4 或 8 个字节中选择 1 个字节(。
你可以让它像这样工作:
case 4:
{
char word[100];
printf("Input characters: ");
if(scanf("%s", word)==1) {
int len = strlen(word);
for(int i=0; i<len; ++i) {
head = delete_word(head, word[i]);
}
}
printList(head);
break;
}
这将允许用户输入一些字符,并且包含其中任何一个字符的所有单词都将被删除。