我发布了类似的问题,但我能够进一步缩小问题的范围。我很确定我知道问题是什么,但我一直在想弄清楚如何解决它。
//assuming typedef struct person person;
struct person{
char first_n[100];
char last_n[100];
char middle_n[100];
struct person* next;
};
void open_file_and_read(char* file){
FILE* fp = fopen(file_name, "r");
if (fp != NULL){
while (!feof(fp)){
person* person = malloc(sizeof(person));
person->next = NULL;
while (fscanf(fp, "%s %s %s", person->first_n, person->last_n, person->middle_n) == 3){
add_to_contacts(person);
}
}
}
}
void open_write_file(char* file){
FILE* filep = fopen(file, "w");
person* copy;
for (copy = front; copy != NULL; copy=copy->next){
fprintf(filep, "%s %s %s\n", copy->last_n, copy->first_n, copy->middle_n);
}
fclose(filep);
}
void add_to_contacts(person* person){
printf("last_name: %s", person->last_name);
if (head == NULL){
person->next = head;
head = person;
else{
person->next = head;
head = person;
}
}
int main(int argc, char * argv[])
{
char* inputFilename = argv[1];
if (inputFilename == NULL){
inputFilename = "myRolodex";
}
open_read_file(inputFilename);
char command;
while (command != 'Q' && command != 'q'){
printf("STARTING TO READ COMMAND\n");
command = read_command(inputFilename);
evaluate_command(command);
}
open_write_file(inputFilename);
clear_rolodex();
printf将文件中的所有内容打印为一个节点。例如:文件包含:
Bob Lee Steve
Mike Steven Noel first, last, middle
James Nguyen Lee
printf打印出LeeStevenNguyen
。这些应该是分开的。
我认为问题与malloc只被调用一次有关,而我真正需要的是每次扫描时调用它。但是我无法在person* person = malloc(sizeof(person));
循环下移动while...fscanf
,因为fscanf依赖于已创建person
。那么我该怎么做每个新人的mallocing。类似的任务将在几个小时内到期,我花了最后10个小时试图让一切工作,我相信这是最重要的部分。
谢谢
编辑以获取更多详细信息:我的add_to_contacts
函数中有一个print语句,用于打印出node-> lasts_name。我还在排序功能(未发布)之前添加了一个print语句,并且无限打印
答案 0 :(得分:0)
有几种方法可以解决这个问题。
我认为最符合你想要的是:
person* person = malloc(sizeof(person));
person->next = NULL;
while (fscanf(fp, "%s %s %s", person->first_n, person->last_n, person->middle_n) == 3){
add_to_contacts(person);
person = malloc(sizeof(person));
person->next = NULL;
}
free(person);
这假设add_to_contacts
插入了malloc&#d; d
指向数据结构的指针,所以我们需要下一个fscanf
来放置它
数据位于不同的位置。
完成此操作后,将始终分配一个person*
最后实际上并没有传递给add_to_contacts
,所以我们
当循环退出时,可以而且应该释放该指针。
略有变化
person* person = malloc(sizeof(person));
while (fscanf(fp, "%s %s %s", person->first_n, person->last_n, person->middle_n) == 3){
person->next = NULL;
add_to_contacts(person);
person = malloc(sizeof(person));
}
free(person);
(这个想法是唯一需要person->next = NULL;
的东西
这大概是add_to_contacts(person)
,并推迟
person->next = NULL;
直到最后一刻我们不必打电话
它在循环之外以及循环内部。)
另一种(完全不同的)方法是
声明局部变量,让fscanf
写入它们,
并将它们复制到循环内新分配的person
。
第三种方法是使person
成为堆栈分配(不是malloc< d; d)变量,
并让add_to_contacts
按顺序制作自己的malloc副本
将副本插入数据结构中。
但最后两个选项涉及fscanf
将数据写入一个地方
然后必须将其复制到另一个,以便将其放入更大的结构中。看来你可能想避免复制。
答案 1 :(得分:0)
关于这部分问题:
相信问题与malloc只被调用一次有关,当我真正需要的是每次我scanf时调用它。但是我无法移动person * person = malloc(sizeof(person));在while ... fscanf循环下,因为fscanf依赖于已经创建了一个人
建议fscanf()为局部变量(记得在格式参数上使用长度修饰符以避免缓冲区溢出。
然后,在循环内,malloc,错误检查,复制变量,调用函数将malloc内存插入到链表中。