gpt4 book ai didi

c - 陷入 C 词典项目

转载 作者:行者123 更新时间:2023-11-30 15:03:05 25 4
gpt4 key购买 nike

我更喜欢创建一个 Dictionary 对象并向其中添加 3 个单词。我的程序没有编译错误,但在第二个 for 循环中出现运行时错误,问题出在 addNewWord 函数中吗?我需要传递一个指向 DictionaryWord 对象的指针吗?

请帮助我。

#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>

typedef struct{
char* name;
char* mean;
} Words;

typedef struct{
Words* word;
int size;
} Dictionary;

Dictionary createNewDictionary();
Words createNewWord();
void addNewWord(Words newword, Dictionary dic);

Dictionary createNewDictionary(){
Dictionary dic;
dic.size = 0;
dic.word = (Words*)malloc(dic.size*sizeof(Words));
return dic;
}

Words createNewWord(){
Words newword;
newword.name = (char*)malloc(30*sizeof(char));
newword.mean = (char*)malloc(30*sizeof(char));
printf("============================\n");
printf("Enter word: ");
scanf("%[^\n]", newword.name);
fflush(stdin);
printf("\nEnter meaning: ");
scanf("%[^\n]", newword.mean);
return newword;
}

void addNewWord(Words newword, Dictionary dic){
dic.size++;
dic.word = (Words*)realloc(dic.word,dic.size*sizeof(Words));
strcpy(dic.word[dic.size-1].name, newword.name);
strcpy(dic.word[dic.size-1].mean, newword.mean);
}

int main(){
Dictionary d = createNewDictionary();
for (int i=0;i<3;i++){
addNewWord(createNewWord(), d);
}
return 0;
}

最佳答案

您的代码存在很多问题:

鉴于英语中最长的单词约为 30 个字符,这种大小分配对于该单词来说是现实的,但对于定义来说则不然:

newword.name = (char*)malloc(30*sizeof(char));
newword.mean = (char*)malloc(30*sizeof(char));

这没有什么明显的意义:

dic.size = 0;
dic.word = (Words*)malloc(dic.size*sizeof(Words));

您在零上调用了malloc()!只有稍后的 realloc() 才能幸免。即使是故意的,也确实值得评论。

这实际上不起作用,因为 fflush() 用于输出流:

fflush(stdin);

参见:How to clear input buffer in C?无论您使用什么修复方法,都必须适用于两个 scanf() 调用,而不仅仅是一个!

根据@Jarvis,这不起作用:

dic.word = (Words*)realloc(dic.word,dic.size*sizeof(Words));
strcpy(dic.word[dic.size-1].name, newword.name);
strcpy(dic.word[dic.size-1].mean, newword.mean);

因为您没有在 dic 中为 namemean 分配任何空间,因此您正在复制到随机内存中。

根据@Jarvis,不起作用:

void addNewWord(Words newword, Dictionary dic){
dic.size++;
dic.word = (Words*)realloc(dic.word,dic.size*sizeof(Words));

您按值传递 dic,因此在 addnewWord() 中您拥有 dic 的副本,因此原始 dic size 将与调用之前相同!

内存泄漏:

addNewWord(createNewWord(), d);

您将句柄放到了 createNewWord() 返回的内容上,因此您永远无法释放它 malloc() 所占用的内存

malloc()内存,但没有提供最终释放它的方法。

在这种情况下,按值传递和返回结构是一场灾难,因为数据不断被复制。至少它效率低下,最坏的是它有像上面的 size 问题一样的错误。不要冒险,假装它们只能通过指针传递和返回,这样您就可以安全行事并获得更好的结果。

下面是对您的代码(用C)的修改,其中包括修复、风格调整以及对一致术语的尝试。它还提供了一些最小的测试代码和释放数据的能力:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_WORD_LENGTH 30
#define MAX_DEFINITION_LENGTH 1024

typedef struct entry {
char *word;
char *definition;
} Entry;

typedef struct dictionary {
Entry *entries;
int num_entries, max_entries;
} Dictionary;

Dictionary *createNewDictionary() {
Dictionary *dictionary = malloc(sizeof(*dictionary));

dictionary->num_entries = 0;
dictionary->max_entries = 1;
dictionary->entries = calloc(dictionary->max_entries, sizeof(*dictionary->entries));

return dictionary;
}

void freeEntry(Entry *entry) {
free(entry->word);
free(entry->definition);
free(entry);
}

void freeDictionary(Dictionary *dictionary) {
for (--dictionary->num_entries; dictionary->num_entries >= 0; --dictionary->num_entries) {
// we can't call freeWord() here -- why.
free(dictionary->entries[dictionary->num_entries].word);
free(dictionary->entries[dictionary->num_entries].definition);
}

free(dictionary->entries);
free(dictionary);
}

void purgeInput() {
int c;

while ((c = getchar()) != '\n' && c != EOF) { }
}

Entry *requestNewEntry() {
Entry *entry = malloc(sizeof(*entry));
entry->word = malloc(MAX_WORD_LENGTH);
entry->definition = malloc(MAX_DEFINITION_LENGTH);

printf("============================\n");
printf("Enter word: ");
scanf("%[^\n]", entry->word);

purgeInput();

printf("\nEnter definition: ");
scanf("%[^\n]", entry->definition);

purgeInput();

return entry;
}

void addNewEntry(Entry *entry, Dictionary *dictionary) {
if (dictionary->num_entries == dictionary->max_entries) {
dictionary->max_entries *= 2;
dictionary->entries = realloc(dictionary->entries, dictionary->max_entries * sizeof(*dictionary->entries));
// check if realloc returns NULL and if so, handle the error.
}

dictionary->entries[dictionary->num_entries].word = strdup(entry->word);
dictionary->entries[dictionary->num_entries].definition = strdup(entry->definition);

dictionary->num_entries++;
}

int main() {
Dictionary *d = createNewDictionary();

for (int i = 0; i < 3; i++) {
Entry *e = requestNewEntry();

addNewEntry(e, d);

freeEntry(e);
}

printf("\nRead: ");
for (int i = 0; i < d->num_entries; i++) {
printf("%s (%lu chars) ", d->entries[i].word, strlen(d->entries[i].definition));
}
printf("\n");

freeDictionary(d);

return 0;
}

创建双关语词典

> ./a.out
============================
Enter word: silkworm

Enter definition: Two silkworms had a race but ended up in a tie.
============================
Enter word: horse

Enter definition: A horse is a stable animal.
============================
Enter word: termite

Enter definition: A termite walks into a pub and asks, "Is the bar tender here?"

Read: silkworm (47 chars) horse (27 chars) termite (62 chars)
>

关于c - 陷入 C 词典项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40836609/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com