我写入文件的函数:
Record_t * load_Record(FILE * infile)
{
Record_t *r;
char title[TITLE_SIZE];
char [MEDIUM_SIZE];
int ID, rating;
if ((fscanf(infile,"%d: %s %d", &ID, medium, &rating) != 3 && fgets(title, TITLE_SIZE, infile))){
return NULL;
}
printf("medium is: %s title is: %s\n", medium, title);
r = create_Record(medium, title);
set_Record_rating(r, rating);
return r;
}
其中Record_t定义为:
typedef struct Record {
int ID;
char * title;
char * medium;
int rating;
} Record_t;
我的主要人物:
#include "Record.h"
#include <stdlib.h>
int main()
{
char * title = "The Queen";
char * medium = "DVD";
FILE * pfile ;
struct Record *t = create_Record(medium, title); //creates a record
struct Record *s;
set_Record_rating (t, 3);
print_Record(t);
pfile = fopen("output.txt", "w");
save_Record(t, pfile);
fclose(pfile);
destroy_Record(t); //de-allocates memory
pfile = fopen("output.txt", "r");
if(!(s = load_Record(pfile))){
return 1;
}
print_Record(s);
fclose(pfile);
destroy_Record(s);
return 0;
}
写入文件后output.txt:
1: DVD 3 The Queen //checked for excess whitespace(has newline however)
终端输出:
1: The Queen DVD 3
medium is: DVD title is: � //title being saved inappropriately
@
2: �
@ DVD 3
现在我的 fgets 功能错了!由于某种原因,标题被不当地保存
我正在使用以下标志进行编译: gcc -ansi -std = c89 -pedantic -Wmissing-prototypes -Wall test.c Record.c -o test
其中test.c是我的主要
答案 0 :(得分:4)
char * medium;
这应该是
char medium[SOME_CONSTANT]; // or char* medium = malloc(x); if you need the
// memory to persist after the function returns
这样你实际上medium
指向你拥有的一些记忆。就像现在一样,你的指针指向垃圾,你期望fscanf
将字符串保存在它指向的内存中。
如果某个函数似乎返回指向某个神奇创建的内存的指针,那么最好检查两次文档(除非该函数碰巧是愚蠢的strdup
)。该函数实际上需要指向某个已经分配的内存的指针,或者返回一个指向由malloc
的家人分配的内存块的指针,在这种情况下,您需要负责解除分配它。
只有在非常罕见的情况下,函数才会返回指向内存的指针,而不需要使用预分配的缓冲区而不需要malloc
d(当返回的字符串具有不可预测的大小时,尤其就像它是fscanf
)。
答案 1 :(得分:2)
您没有为媒体分配缓冲区:
char * medium;
这只是创建一个指向名为medium的char的指针,你没有保留任何内存空间来读入。这将为medium:
分配256个字节(允许您读取最多256个字符)medium = malloc(256);
或者你可以在堆栈上分配:
char medium[256];
考虑到你遇到的问题,我建议在堆栈上使用分配,然后只需读取和写入文件结构 - 它可以避免你自己解析字段等等以牺牲磁盘空间为代价(你可能会写出很多空白字符)但在这种情况下,这种浪费可以忽略不计。
fwrite(t, sizeof(Record_t), 1, pFile);
fread(t, sizeof(Record_t), 1, pFile);
答案 2 :(得分:1)
有几种方法:
您没有为其分配空间来读取字符串。你需要:
char medium[100];
您没有正确检查错误:
if (!(fscanf(infile,"%d: %s %d", &ID, medium, &rating)
应该是:
if (fscanf(infile,"%d: %s %d", &ID, medium, &rating) != 3 ...
您需要明确地测试您是否获得了您希望阅读的所有值。
在没有对所有代码进行深入分析的情况下,这表面很难理解。请注意,您需要确保不要尝试将medium
返回到调用代码。如果create_record()
做了合理的工作,这应该没问题。奇怪的是create_record()
没有被告知记录ID。