我正在用C语言编写一个程序,我需要创建一个结构数组,将结构数组保存到文件中,然后打开该文件,读取该文件,并将该文件的内容复制到一个数组中结构(这个称为“朋友”的特殊结构包含三个字符串)。但是,如果数组拥有三个这样的朋友:
John Doe 234-1230 (string, string, string) <br>
Kool Kat 343-3413<br>
Suzie Q 234-1234<br>
一旦我将这个数组保存到一个文件中,我就可以使用下面的open函数打开它:
Joán Doe 234-2132<br>
Kool Kat 343-3413<br>
Suzie Q 234-1234<br>
或
John Doe 234-2132<br>
Kool Kat 343-3413<br>
Suz Q 234-1234<br>
其中一个字符串(几乎总是结构中的第一个字符串)几乎完全相同,其中一个或多个随机字符被切换出来。谁能告诉我导致这个错误的原因是什么?
void open(friend* book, int* size){
FILE *pRead;
char address[100];
char answer = 'a';
printf("\nWARNING: Any unsaved data in the current phonebook will be lost!");
printf("\nType the file-name you would like to open(press '1' for the default location):");
scanf("%s", &address);
if(strcmp(address, "1") == 0){
strcpy(address, "default.dat");
}
pRead = fopen(address, "r");
if(pRead == NULL){
printf("\nFile not opened\n");
}else{
int counter = 0;
while(!feof(pRead)){
fscanf(pRead, "%s%s%s", book[counter].pFName, book[counter].pLName, book[counter].pNumber);
counter++;
realloc(book, sizeof(friend) * counter);
}
*size = counter;
fclose(pRead);
printf("\n%s has been loaded into the program!", address);
}
}
其他信息:当我继续在同一个文件上调用此函数时,它最终会生成正确的字符串,这让我相信我的保存功能是正确的。这与内存分配有关吗?
这是我的结构代码:
typedef struct Contact{ //creates a struct that holds three strings (first name, last name, phone number) (can be referred to as either Contact or friend
char pFName[20]; //first name of friend
char pLName[20]; //last name of contact
char pNumber[12]; //phone number of contact
}friend;
答案 0 :(得分:2)
我在这里看到一个明确的问题:
while(!feof(pRead)){
fscanf(pRead, "%s%s%s", book[counter].pFName, book[counter].pLName, book[counter].pNumber);
counter++;
realloc(book, sizeof(friend) * counter);
}
你总是读到你不拥有的记忆,然后再问realloc
。此外,您忽略realloc
的返回值。即使您认为它永远不会为NULL,仍然允许重新定位您的数据。这样做会更安全:
while(!feof(pRead)){
book = realloc(book, sizeof(friend) * (counter+1));
fscanf(pRead, "%s%s%s", book[counter].pFName, book[counter].pLName, book[counter].pNumber);
counter++;
}
现在,接受book
可以改变,你需要将它作为双指针传递,或让你的函数返回它。
这里还有其他一些你应该避免的事情,例如feof
测试,你没有检查fscanf
的返回值,而你没有防范缓冲溢出。但是,看到你的输入和输出,我认为这些都不会直接影响到你。
答案 1 :(得分:0)
在读取文件名时,scanf函数出错。
scanf("%s", &address);
你应该删除&amp ;.
但是,这可能不是您问题的原因,因为它适用于大多数系统。基本上这里的问题是scanf("%s", &string)
衰减到指向char的指针[256],而scanf期望char *
类型。这是有效的,因为指针&string
和&string[0]
的表示方式相同。但是,您的代码取决于标准C不保证的事物,它可能在不同的系统中具有不同的行为。