我的任务是写一个显示用户输入的未知记录数的文件。每条记录都有以下字段:名字、姓氏、地址、城市、州、邮政编码和电话号码。
我认为最好的方法是用上面的字段定义一个struct记录,然后声明一个Record
s数组,该数组包含用户输入的所有记录。为此,我将使用循环来获取每条记录的每个字段的输入,然后如果用户希望继续在Record
数组中动态分配额外的空间并继续,直到用户输入no。我在第行遇到访问冲突写入位置错误:
scanf("%s", records[i]->fname);
我的密码怎么了?
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
struct Record;
struct Record
{
char fname[51];
char lname[51];
char address[51];
char city[51];
char state[51];
int zipcode;
int phoneNumber;
};
int main()
{
FILE *fileWriter;
const char filename[] = "data.txt";
char answer = 'y';
int size = 1;
int i = 0;
struct Record **records;
records = malloc(sizeof(*records)*(size));
while(answer == 'y' || answer == 'Y')
{
printf("First Name: \n");
scanf("%s", records[i]->fname);
printf("Last Name: \n");
scanf("%s", records[i]->lname);
printf("Address: \n");
scanf("%s", records[i]->address);
printf("City: \n");
scanf("%s", records[i]->city);
printf("State: \n");
scanf("%s", records[i]->state);
printf("Zipcode: \n");
scanf("%d", records[i]->zipcode);
printf("Phone Number: \n");
scanf("%d", records[i]->phoneNumber);
//stores all record info
printf("Are there anymore records? [y/n] ");
answer = getchar();
if(answer == 'y' || answer == 'Y')
{
size++;
records[i++];
printf("\n");
}
records = realloc(records,sizeof(*records)*(size));
}
//open file
fileWriter = fopen(filename,"wb");
if(fileWriter != NULL)
{
if(fwrite(records,sizeof(*records),size,fileWriter) != 1)
{
fprintf(stderr, "Failed to write to %s\n", filename);
exit(1);
}
fclose(fileWriter);
}
else
{
printf("Error opening file.");
}
}
编辑版本
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
struct Record
{
char fname[51];
char lname[51];
char address[51];
char city[51];
char state[51];
int zipcode;
int phoneNumber;
};
int main()
{
FILE *fileWriter;
const char filename[] = "data.txt";
char answer = 'y';
int size = 1;
int i = 0;
struct Record *records = NULL;
struct Record *records_temp;
while(answer == 'y' || answer == 'Y')
{
struct Record *records_temp = realloc(records,(size)*sizeof(*records));
if(records_temp == NULL)
{
free(records);
}
records = records_temp;
printf("First Name: \n");
scanf("%s", records[i].fname);
printf("Last Name: \n");
scanf("%s", records[i].lname);
printf("Address: \n");
scanf(" %[^\n]", records[i].address);
printf("City: \n");
scanf("%s", records[i].city);
printf("State: \n");
scanf("%s", records[i].state);
printf("Zipcode: \n");
scanf("%d", &records[i].zipcode);
printf("Phone Number: \n");
scanf("%d", &records[i].phoneNumber);
//stores all record info
printf("Are there anymore records? [y/n] ");
answer = getchar();
if(answer == 'y' || answer == 'Y')
{
size++;
records[i++];
printf("\n");
}
//open file
fileWriter = fopen(filename,"wb");
if(fileWriter != NULL)
{
if(fwrite(records,sizeof(*records),size,fileWriter) != 1)
{
fprintf(stderr, "Failed to write to %s\n", filename);
exit(1);
}
fclose(fileWriter);
}
else
{
printf("Error opening file.");
}
}
}
最佳答案
因为没有为records
中的第一个实体分配内存,所以会得到segfault。
所以要解决你需要
records[size-1] = malloc(sizeof(Records));
这样说:
你有一个指向
records
的指针。当你这么做的时候
records = malloc(sizeof(*records)*(size));
实际上,您需要指向
Records
的size
指针。但这还不够,您需要分配另一个内存来存储实际的
Records
,因此我们必须records[size - 1] = malloc(sizeof(Records));
注意:如果
Records
>1,则应:int i = 0;
for(;i < size; i++) {
records[i] = malloc(sizeof(Records));
}
除此之外,正如Arjun已经解释过的,为什么要使用
size
并修复新内存中的Records **
部分,因为如果Records *
失败,它将返回realloc
,而在最坏的情况下,最终会出现内存泄漏或另一个segfault,无论哪种情况——这对程序都不好。请参见Arjun's post
关于c - 将数据写入动态数组时出现段错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30448605/