我的作业要求我们缩短用户输入句子的单词。然后将缩短的单词放入链表中。当代码的齿轮卡住时:句子中的最后一个单词被保存到每个节点中。应该实现什么修复,以便代码每次在节点中放置一个差异字。
注意:我查看了涉及memcpy的问题,并使用0和\0事先填充数组来实现。我还改变了memcpy的论点,有&和没有&。我还使用了memmove和strncpy。没有问过"memcpy in for loop将数组的子字符串复制到节点"的变体。
这是我的代码。感谢您在回答的评论中推荐学习资源链接到 c 或 java。以及改进代码的建议。当然,如果您对我的问题有更简洁/准确的版本,我很乐意更新它。谢谢!
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
typedef struct node
{
char *four_letters;
struct node *next_node;
}node;
struct node* head= NULL;
char sentence[120][40]={0}, four_letters[40]={0}; // Tried ,"0".
int word, num_words=-1;
void scan(); void print(); void sentence_into_list();
void add(struct node **head, char *four_letters);
void display(struct node *head);
int main()
{
scan();
printf("n");
print();
printf("n");
sentence_into_list();
display(head);
return 0;
}
void scan()
{
for(word=0;;word++)
{
scanf("%s",sentence[word]);
num_words++;
if(getchar()=='n')
break;
}
}
void print()
{
for(word=0;word<=num_words;word++)
{
printf("%s ", sentence[word]);
}
}
void sentence_into_list()
{
for (word=0;word<=num_words;word++)
{
memcpy(four_letters, sentence[word], 4); //tried & //tried strncpy, memmove.
add(&head, four_letters);
}
}
void add(struct node **head, char *four_letters)
{
struct node *new_node = malloc(sizeof(struct node));
new_node->four_letters = four_letters;
new_node->next_node = *head;
*head=new_node;
}
void display(struct node* head)
{
struct node *current;
current = head;
if(current!=NULL)
{
printf("List:");
do
{
printf("%s ",current->four_letters);
current = current->next_node;
}
while(current!=NULL);
printf("n");
}
else
{
printf("emptyn");
}
}
句子中的最后一个单词被保存到每个节点中。
发生这种情况是因为列表中所有节点four_letters
指针指向相同的内存位置four_letters
[char
全局声明的缓冲区 -four_letters[40]={0};
]。因此,无论four_letters
的最后一个值是什么,都将反映在所有节点中。
解决此问题的一种方法是将足够
大的内存分配给节点four_letters
指针,并将four_letters
的内容复制到其中。或者,您可以使用strdup
为您执行此操作。
因此,在add()
函数中,将其替换为
new_node->four_letters = four_letters;
有了这个
new_node->four_letters = strdup(four_letters);
strdup
创建传递给它的字符串的副本。它返回一个指向新分配的内存的指针,因此,您应该在完成它后free
它,如下所示:
free (node_ptr->four_letters); //node_ptr is pointer to current node
在释放列表节点的动态分配内存时,请确保首先释放节点结构的动态分配成员,然后释放节点本身。
解决此问题的另一种方法是-
不要在结构node
中使用指向char
的指针,而是将char
数组作为node
结构的成员,如下所示:
typedef struct node
{
char four_letters[5]; // 5 because it is suppose to keep the four letters only and +1 is for null-terminating character
struct node *next_node;
}node;
并将传递给add()
four_letters
的内容复制到结构节点成员four_letters
。有了这个,您无需注意释放内存。
你的代码还有一个问题-
在函数sentence_into_list()
中,你正在做:
memcpy(four_letters, sentence[word], 4);
add(&head, four_letters);
在这里,您将sentence[word]
的前4
个字符复制到four_letters
,但您还应该在缓冲区four_letters
的第5
个位置添加 null 终止字符,然后再将其传递给add()
,如下所示:
four_letters[4] = ' ';
C 语言没有本机字符串类型。在 C 中,字符串实际上是以空字符