我正在构建一个链表,该链表应该只包含一个单词的单个实例,由于某种原因,我读入的第一个单词被跳过,在我继续构建链表时,输出会剪切下一个单词。对于第一个单词,它还会跳过checkforRepeat函数。我不知道这一点出了什么问题,所以任何帮助都将不胜感激!功能输入:列表单词hello单词包含结束
编辑
我弄清楚了为什么我的函数没有被调用,但现在我很难弄清楚为什么内存会被戳上,因为当我插入输入时,我会得到list,list,word,hello,contains,end而不是list,word、hello,includes,end。
typedef struct NODE{
char* word;
struct NODE* next;
struct NODE* prev;
struct NODE* first;
struct NODE* last;
} node;
int checkforRepeat(node** first_node, char* wordtofind, int listsize){
node* findrepeats = *first_node;
if (findrepeats == NULL) {
return 0;
}
printf("nnWord to find: %snn", wordtofind);
printList(*first_node);
printf("n");
int i = 1;
while (1) {
if (findrepeats->next == NULL) {
break;
}
else {
printf(" %s, ", findrepeats->word);
if (strcmp(wordtofind, findrepeats->word) == 0 ) {
printf("|%s|, ", findrepeats->word);
return 1;
}
else findrepeats = findrepeats->next;
}
i++;
}
return 0;
}
void addNode(char* newword, node** address_of_first_node, int* sizeoflist){
if(*newword > 47 && *newword < 58){
return;
}
node *added_node;
node *head = *address_of_first_node;
added_node = malloc(sizeof(node));
printf("nnWord before function: %snn", newword);
if (checkforRepeat(address_of_first_node, newword, *sizeoflist) == 1) {
return;
}
added_node->word = newword;
added_node->next = NULL;
if(head == NULL){
*address_of_first_node = added_node;
added_node->prev = NULL;
added_node->first = *address_of_first_node;
added_node->last = added_node;
}
else{
node *last_node = head;
while (1) {
if (last_node->next == NULL) break;
else {
last_node->last = added_node;
last_node = last_node->next;
}
}
last_node->next = added_node;
added_node->first = *address_of_first_node;
added_node->prev = last_node;
added_node->last = added_node;
}
*sizeoflist = *sizeoflist + 1;
}
void printList(node *data){
while (1) {
if (data->next == NULL) {
printf("%s", data->word);
break;
}
printf("%s,", data->word);
data = data->next;
}
}
int main(){
node* list_of_nodes = NULL;
char* deletednodes = malloc(20 * sizeof(char));
int* sizeoflist = malloc(sizeof(int));
*sizeoflist = 0;
int j = 0;
while (1) {
char* wrd = malloc(20);
if (scanf("%s", wrd) == EOF) break;
addNode(wrd, &list_of_nodes, sizeoflist);
}
printList(list_of_nodes);
}
以下是可以工作的代码,添加了相当全面的调试。主要更改是删除checkforRepeat()
中的测试if (i == listsize)
。由于不再需要列表大小,并且checkforRepeat()
代码不需要指向struct NODE
的指针,因此存在连锁效应;一个简单的指针就足够了。
此外,你有:
struct NODE{
char* word;
struct NODE* next;
struct NODE* prev;
struct NODE* first;
struct NODE* last;
} typedef node;
将关键字 在声明中放置声明说明符开头以外的存储类说明符是过时功能更新代码以检查内存分配失败,当一个字被重复时,更新代码以避免 样本输出(源typedef
放在结构定义之后在技术上还没有错,但它使用了C.C11§6.11.5存储类说明符的过时功能:main()
中分配的字泄漏(尽管free()
与分配相距遥远,令人不安(,并避免节点泄漏。然而,代码并没有试图在最后释放列表,即使这样做并不困难。#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct NODE
{
char *word;
struct NODE *next;
struct NODE *prev;
struct NODE *first;
struct NODE *last;
} node;
static
int checkforRepeat(node *first_node, char *wordtofind)
{
printf("-->> %s(): check for [%s]n", __func__, wordtofind);
node *findrepeats = first_node;
if (findrepeats == NULL)
{
printf("<<-- %s(): empty list, word [%s] not foundn", __func__, wordtofind);
return 0;
}
printf("Word to find: %sn", wordtofind);
while (findrepeats != NULL)
{
printf(" %s, ", findrepeats->word);
if (strcmp(wordtofind, findrepeats->word) == 0)
{
printf("|%s|, ", findrepeats->word);
printf("n<<-- %s(): found word [%s], return 1n", __func__, wordtofind);
return 1;
}
findrepeats = findrepeats->next;
}
printf("n<<-- %s(): did not find word [%s], return 0n", __func__, wordtofind);
return 0;
}
static
void addNode(char *newword, node **address_of_first_node)
{
printf("-->> %s(): [%s]n", __func__, newword);
if (*newword > 47 && *newword < 58)
{
return;
}
printf("---- %s(): [%s]n", __func__, newword);
node *head = *address_of_first_node;
printf("Word before function: %sn", newword);
if (checkforRepeat(head, newword) == 1)
{
printf("<<-- %s(): repeated word: %sn", __func__, newword);
return;
}
node *added_node = malloc(sizeof(node));
if (added_node == NULL)
{
free(newword);
fprintf(stderr, "failed to allocate memory for new noden");
exit(EXIT_FAILURE);
}
added_node->word = newword;
added_node->next = NULL;
if (head == NULL)
{
*address_of_first_node = added_node;
added_node->prev = NULL;
added_node->first = *address_of_first_node;
added_node->last = added_node;
}
else
{
node *last_node = head;
while (1)
{
if (last_node->next == NULL)
break;
else
{
last_node->last = added_node;
//printf("%s.n", last_node->last->word);
last_node = last_node->next;
}
}
last_node->next = added_node;
added_node->first = *address_of_first_node;
added_node->prev = last_node;
added_node->last = added_node;
}
printf("<<-- %s(): added node for [%s]n", __func__, newword);
}
static void printList(const char *tag, node *node)
{
printf("%s:n", tag);
while (node != NULL)
{
printf("Word [%s]n", node->word);
node = node->next;
}
}
int main(void)
{
node *list_of_nodes = NULL;
while (1)
{
char *wrd = malloc(20);
if (wrd == NULL)
{
fprintf(stderr, "failed to allocate memory for new wordn");
exit(EXIT_FAILURE);
}
if (scanf("%19s", wrd) == EOF)
break;
addNode(wrd, &list_of_nodes);
printList("After adding word", list_of_nodes);
}
/* ...omitted... */
return 0;
}
skip19.c
,程序skip19
(:$ skip19 <<< 'hello world how are you doing world'
-->> addNode(): [hello]
---- addNode(): [hello]
Word before function: hello
-->> checkforRepeat(): check for [hello]
<<-- checkforRepeat(): empty list, word [hello] not found
<<-- addNode(): added node for [hello]
After adding word:
Word [hello]
-->> addNode(): [world]
---- addNode(): [world]
Word before function: world
-->> checkforRepeat(): check for [world]
Word to find: world
hello,
<<-- checkforRepeat(): did not find word [world], return 0
<<-- addNode(): added node for [world]
After adding word:
Word [hello]
Word [world]
-->> addNode(): [how]
---- addNode(): [how]
Word before function: how
-->> checkforRepeat(): check for [how]
Word to find: how
hello, world,
<<-- checkforRepeat(): did not find word [how], return 0
<<-- addNode(): added node for [how]
After adding word:
Word [hello]
Word [world]
Word [how]
-->> addNode(): [are]
---- addNode(): [are]
Word before function: are
-->> checkforRepeat(): check for [are]
Word to find: are
hello, world, how,
<<-- checkforRepeat(): did not find word [are], return 0
<<-- addNode(): added node for [are]
After adding word:
Word [hello]
Word [world]
Word [how]
Word [are]
-->> addNode(): [you]
---- addNode(): [you]
Word before function: you
-->> checkforRepeat(): check for [you]
Word to find: you
hello, world, how, are,
<<-- checkforRepeat(): did not find word [you], return 0
<<-- addNode(): added node for [you]
After adding word:
Word [hello]
Word [world]
Word [how]
Word [are]
Word [you]
-->> addNode(): [doing]
---- addNode(): [doing]
Word before function: doing
-->> checkforRepeat(): check for [doing]
Word to find: doing
hello, world, how, are, you,
<<-- checkforRepeat(): did not find word [doing], return 0
<<-- addNode(): added node for [doing]
After adding word:
Word [hello]
Word [world]
Word [how]
Word [are]
Word [you]
Word [doing]
-->> addNode(): [world]
---- addNode(): [world]
Word before function: world
-->> checkforRepeat(): check for [world]
Word to find: world
hello, world, |world|,
<<-- checkforRepeat(): found word [world], return 1
<<-- addNode(): repeated word: world
After adding word:
Word [hello]
Word [world]
Word [how]
Word [are]
Word [you]
Word [doing]
$