gpt4 book ai didi

c - 从文件中读取并在动态结构上传输

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

我正在尝试解决此练习:

Create the files stringhe.h stringhe.c that let you use the following structures and function"

struct stringa {
unsigned char length;
char *s;
};

struct stringa *read_stringhe_bin(const char *filename, unsigned int *pn);

The structure contains the length field that contains the length of the string (possibly 0) and s field that points to a zero-terminated string (of length length). The function takes as a parameter a file name that is to be opened in read mode untranslated (binary) and a pointer to an unsigned int variable in which you will have to enter the number of strings in the file.

The file consists of a sequence of length elements variable in which a byte indicating the length n of the string and below there are n bytes containing the characters of the string.

The function must return a pointer to a new memory area (dynamically allocated heap) containing all strings read from the file. The number of strings is not known a priori and not limited.

It can be bound by the code. Even the s string element must be dynamically allocated heap.

这是我的代码:

stringhe.h

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

struct stringa {
unsigned char length;
char *s;
};

#ifndef READ
#define READ
struct stringa *read_stringhe_bin(const char *filename, unsigned int *pn);
#endif // !READ

stringhe.c

#include "stringhe.h"

struct stringa *read_stringhe_bin(const char *filename, unsigned int *pn) {
FILE *f;
f = fopen(filename, "r+b");
if (f == NULL) exit(1);

struct stringa *lista;
lista = malloc(0);
lista->s = malloc(0);

for (int i = 0; ; i++) {
char a;

fseek(f, 1, SEEK_CUR);
if (fgetc(f) == EOF) break;

fseek(f, -2, SEEK_CUR);
fread(&a, 1, 1, f);

lista = (struct stringa *)realloc (lista, sizeof(struct stringa) * (size_t)(i + 1));
lista[i].length = a;
lista[i].s = malloc(sizeof(char) * (size_t)a);

fread(lista[i].s, 1, (size_t)a, f);
lista[i].s[a] = '\0';
(*pn)++;
}

fclose(f);

return lista;
}

我向函数传递了以下二进制文件:

05 43 69 61 6F 21 00 03 61 62 63 0E 50 72 6F 67
72 61 6D 6D 61 7A 69 6F 6E 65

翻译成:

.Ciao!..abc.Prog
rammazione

所以...我的功能通过调试似乎完美地工作,但是当我将它上传到我们教授的网站以查看它是否真的有效时,它说 main(由教授,我看不到)错误地结束了。所以我怀疑我在内存分配或类似的事情上做错了什么。你能帮助我理解错误并可能改进我的代码以使其更强大吗?

最佳答案

您的代码存在多个问题:

您使用"r+b" 模式打开文件。更新无用且容易出错,只需使用 "rb"

如果文件无法打开,您可能只是返回 NULL 而不是退出程序。

lista = malloc(0);
lista->s = malloc(0);

malloc(0) 可能会返回 NULL 或您不应写入的对象的地址。你应该这样做:

lista = NULL;

为字符串字符分配空间时:

lista[i].s = malloc(sizeof(char) * (size_t)a);

您应该为从文件中读取字节后设置的终止'\0' 分配一个额外的字节。这样做:

lista[i].s = malloc(a + 1);

试图检查文件结尾很麻烦,而且流实际上可能不支持。只需将一个字节的大小读入 int,检查 EOF,然后为内容分配和读取指定数量的字节:

    int a;

a = fgetc(f);
if (a == EOF) break;

lista = realloc(lista, sizeof(*lista) * (size_t)(i + 1));
lista[i].length = a;
lista[i].s = malloc(a + 1);
lista[i].s[a] = '\0';

if (fread(lista[i].s, 1, a, f) != a) {
// file format error, ignore this incomplete string
break;
}

您还应该检查 mallocrealloc 分配内存的潜在失败并优雅地返回 NULL

最后,您返回分配的字符串数的方式不正确:

(*pn)++;

您不知道 *pn 在进入您的函数时是否为 0...它可能只是在 main() 中未初始化.通过在解析循环结束时设置一次来解决这个问题:

*pn = i;

另外,为什么要用 #ifndef READ 等将 stringe.h 中的函数声明包围起来。这种保护 的目的是什么?

关于c - 从文件中读取并在动态结构上传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38943816/

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