gpt4 book ai didi

c - 从文件错误中读取单词

转载 作者:太空宇宙 更新时间:2023-11-04 03:32:48 25 4
gpt4 key购买 nike

我在从文件中读取单词并将其传递给二叉树时遇到了问题。当我调试它时,它说:

Unhandled exception at 0x76E7773B(ntdll.dll) in Projekt.exe: 0.C00000005:
Access violation reading location 0x0037902A.

这是源代码:

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

typedef struct Tree {
int val;
char *word;
struct Tree *left;
struct Tree *right;
} Tree;

void show(Tree *hd) {
if (hd != NULL) {
show(hd->left);
show(hd->right);
printf("%s -- %d\n", hd->word, hd->val);
}
}

void zero(Tree *aTree) {
if (aTree == NULL)
return;

zero(aTree->left);
free(aTree);
zero(aTree->right);
}

int alpha(char *word1, char *word2) {
if (word1[0] == 0 && word2[0] == 0)
return 2;
else
if (word1[0] == word2[0])
return alpha(&word1[1], &word2[1]);
else
if (word1[0] < word2[0])
return 1;
else
return 0;
}

Tree *create(char *word) {
Tree *temp;
temp = (Tree*)malloc(sizeof(Tree));
temp->left = temp->right = NULL;
temp->val = 1;
temp->word = (char*)malloc(sizeof(char));
strcpy(temp->word, word);
return temp;
}

Tree *insert(Tree *aTree, char *word) {
if (aTree == NULL) {
aTree = create(word);
} else
if (alpha(aTree->word, word) == 0) {
aTree->left = insert(aTree->left,word);
} else
if (alpha(aTree->word, word) == 1) {
aTree->right = insert(aTree->right, word);
} else
if (alpha(aTree->word, word) == 2) {
aTree->val++;
}
return aTree;
}

int main(int argc, char *argv[]) {
Tree *myTree = NULL;
char buffer[256] = { 0 };
char temp = 0;
int i = 0;
FILE *fp = fopen(argv[1], "r");
if (fp) {
while (temp != EOF) {
temp = getc(fp);
temp = toupper(temp);
if (temp >= 65 && temp <= 90) {
buffer[i] = temp;
i++;
} else {
if (buffer[0] != 0) {
puts(buffer);
myTree = insert(myTree, buffer);
memset(buffer, 0, sizeof(buffer));
i = 0;
}
}
}
}
fclose(fp);
show(myTree);
return 0;
}

最佳答案

你的程序有几个问题:

  • 在函数中 zero , 你释放指针太早了,你应该移动 free(aTree);作为最后一条语句,否则你会调用未定义的行为,可能是崩溃(但不是你所拥有的,因为你从未调用过这个函数):

    void zero(Tree *aTree) {
    if (aTree != NULL) {
    zero(aTree->left);
    zero(aTree->right);
    free(aTree);
    }
  • 在函数中 alpha ,您在简单循环就足够的地方使用递归。编译器可能会将其转换为循环,但它确实必须这样做。这不是错误,但为什么不使用更惯用的方法,例如:

    int alpha(const char *word1, const char *word2) {
    for (size_t i = 0;; i++) {
    if (word1[i] == '\0' && word2[i] == '\0')
    return 2;

    if (word1[i] == word2[i])
    continue;

    if (word1[i] < word2[i])
    return 1;
    else
    return 0;
    }
    }
  • 在函数中 create ,你为字符串分配了一个字节,这绝对是崩溃的原因。你应该分配 strlen(word) + 1或使用 strdup(word) .您不应该转换 malloc() 的返回值要么:

    Tree *create(const char *word) {
    Tree *temp;
    temp = malloc(sizeof(Tree));
    temp->left = temp->right = NULL;
    temp->val = 1;
    temp->word = strdup(word);
    return temp;
    }
  • 在函数中 insert你打电话alpha多次,这是低效的:你可以使用 switch声明:

    Tree *insert(Tree *aTree, const char *word) {
    if (aTree == NULL) {
    return create(word);

    switch (alpha(aTree->word, word)) {
    case 0:
    aTree->left = insert(aTree->left, word);
    break;
    case 1:
    aTree->right = insert(aTree->right, word);
    break;
    case 2:
    aTree->val++;
    break;
    }
    }
    return aTree;
    }
  • 函数 main有多个问题:

    • 你不检查是否argv[1]提供给程序。它将是 NULL如果程序在没有命令行参数的情况下运行。
    • 您对文件结尾的测试不正确:temp应定义为 int你应该在用 getc() 从文件中读取字节后测试它的值, 命名为 c 是惯用的用于此的变量。
    • 您应该使用字 rune 字而不是硬编码的 ASCII 值。
    • 测试if (c >= 'A' && c <= 'Z')将适用于 ASCII,这在今天几乎是通用的,但使用 isupper(c) 更可靠相反。
    • 您不需要清除 buffer , 设置 '\0'在最后插入单词之前就足够了。
    • 您还应该检查缓冲区溢出并拒绝处理超过 255 个字符的单词。
    • 你不应该调用 fclose(fp)什么时候fpNULL ,这是未定义的行为。

    这是更正后的版本:

    int main(int argc, char *argv[]) {
    Tree *myTree = NULL;
    char buffer[256];
    int c;
    size_t i;
    FILE *fp;

    if (argc < 2) {
    printf("missing argument\n");
    return 2;
    }

    fp = fopen(argv[1], "r");
    if (fp == NULL) {
    printf("cannot open %s\n", argv[1]);
    return 1;
    }
    i = 0;
    while ((c = getc(fp)) != EOF) {
    c = toupper(c);
    if (isupper(c)) {
    if (i < sizeof(buffer))
    buffer[i] = c;
    i++;
    } else {
    if (i > 0 && i < sizeof(buffer)) {
    buffer[i] = '\0';
    puts(buffer);
    myTree = insert(myTree, buffer);
    i = 0;
    }
    }
    }
    fclose(fp);
    show(myTree);
    return 0;
    }

关于c - 从文件错误中读取单词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34964047/

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