fscanf() 不适用于输入
我的函数写入文件:
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;
我的 main:
#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 是我的主要
My Function That writes to the file:
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;
}
where Record_t is defined as:
typedef struct Record {
int ID;
char * title;
char * medium;
int rating;
} Record_t;
My main:
#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 after being written to file:
1: DVD 3 The Queen //checked for excess whitespace(has newline however)
Terminal output:
1: The Queen DVD 3
medium is: DVD title is: � //title being saved inappropriately
@
2: �
@ DVD 3
now my fgets function is wrong! For some reason, the title is being saved inappropriately
i am compiling with the following flags:
gcc -ansi -std=c89 -pedantic -Wmissing-prototypes -Wall test.c Record.c -o test
where test.c is my main
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这应该是
这样,您实际上有
medium
指向您拥有的某些内存。现在,您的指针指向垃圾,并且您期望 fscanf 将字符串保存在它指向的内存中。如果某个函数似乎返回了指向某些神奇创建的内存的指针,您最好检查两次文档(除非该函数恰好是愚蠢的
strdup
)。该函数要么实际上期望一个指向某些已分配内存的指针,要么返回一个指向由malloc
系列中的某个人分配的内存块的指针,在这种情况下,您需要负责解除分配它。只有在极少数情况下,函数才会返回指向内存的指针,而不需要预先分配的缓冲区,也不需要对其进行 malloc(尤其,当返回的字符串大小不可预测时)就像
fscanf
一样)。This should be
So that you actually have
medium
pointing to some memory you own. As it is now, your pointer is pointing to garbage and you're expectingfscanf
to save a string in the memory it points to.If a function ever appears to return a pointer to some magically created memory, you better check the documentation twice (unless that function happens to be the stupid
strdup
). The function either actually expects a pointer to some already-allocated memory, or returns a pointer that points to a block of memory allocated with someone frommalloc
's family, in which case you need to take responsibility for deallocating it.Only in very rare circumstances do functions return a pointer to memory without taking a preallocated buffer in and without having
malloc
d it (especially when the string that is returned is of unpredictable size like it is forfscanf
).您还没有为 media 分配缓冲区:
这只是创建了一个指向名为 media 的字符的指针,您没有保留任何要读入的内存空间。这将为介质分配 256 个字节(允许您读取最多 256 个字符):
或者您可以在堆栈上分配:
鉴于您遇到的问题,我建议在堆栈上使用分配,然后只需读取和写入结构到文件中 - 它使您不必自己解析字段等,从而以磁盘空间为代价(您可能会写出大量空白字符),但在这种情况下这种浪费可以忽略不计。
You've not allocated a buffer for medium:
That just creates a pointer to a char called medium, you've not reserved any memory space to read into. This would allocate 256 bytes (allowing you to read up to 256 characters) for medium:
Or you can allocate on the stack:
Given the issues you're having, I would suggest using allocation on the stack, then just read and write the struct to the file — it saves you from having to parse the fields yourself etc. at expense of disk space (you could be writing out a lot of blank characters) but this wastage would be negligible in this scenario.
几种方法:
您没有为其分配读取字符串的空间。您需要:
您没有正确检查错误:
应该是:
您需要显式测试是否获得了预期读取的所有值。
如果没有对所有代码进行深入分析,这只是停留在表面。请注意,您需要确保您没有尝试将
medium
返回给调用代码。如果create_record()
完成了合理的工作,这应该没问题。奇怪的是create_record()
没有被告知记录 ID。Several ways:
You've not allocated the space for it to read the string into. You need:
You don't check for errors properly:
should be:
You need to explicitly test that you got all the values you expected to read.
That's scratching the surface without a deep analysis of all the code. Note that you'll need to be sure that you are not trying to return
medium
to the calling code. This should be OK ifcreate_record()
does a reasonable job. It is odd thatcreate_record()
isn't told the record ID.