2016-06-28 12 views
0

以下代码将二进制数据写入二进制文件/从二进制文件读取二进制数据。写入成功,根据fread返回值,读取成功。但最后两三个值将永远是垃圾,我通过增加减小数组大小来验证这一点。无法将数据从二进制文件读取到结构指针数组中

如果我们在写入后立即读取文件,那么值将会很好。但是,如果我们在写入后关闭程序一次,然后再以第一次操作再次运行程序,然后将最后几个值作为垃圾进行打印。为什么这样 ?

#include<stdio.h> 
#include<stdlib.h> 
#define MAX 7 

void write(FILE *); 
void read(FILE *); 

int flag=0; 

struct emp 
{ 
char name[20]; 
int id; 
float salary; 
}*e[MAX]; 

void write(FILE *f) 
{ 
int i=0,check=0; 

flag=1; 
for(i=0;i<MAX;i++) 
{ 
    e[i]=malloc(sizeof(struct emp)); 
    if(e[i]) 
    { 
     printf("\nEnter Name id salary\n"); 
     scanf("%s %d %f",e[i]->name,&e[i]->id,&e[i]->salary); 
     //printf("\n----------%s %d %f\n",e[i]->name,e[i]->id,e[i]->salary); 
     //fflush(stdin); 
    } 
    else 
    { 
     printf("\nError allocating Memory\n"); 
     exit(0); 
    } 
} 
check= fwrite(*e,sizeof(struct emp),MAX,f); 
if(check!=MAX) 
{ 
    printf("\nerror writing to file\n"); 
} 
else 
    { 
    printf("\nwritten successfully to file\n"); 
    } 
} 

void read(FILE *f) 
{ 
int i=0; 

if(flag==0) //reading file right after running program 
{ 
    for(i=0;i<MAX;i++) 
    { 
     e[i]=malloc(sizeof(struct emp)); 
     if(e[i]==NULL) 
     { 
      printf("\nError Allocating Memory for read\n"); 
      exit(0); 
     } 
    } 
} 

if(fread(*e,sizeof(struct emp),MAX,f)==MAX) 
{ 
    for(i=0;i<MAX;i++) 
    { 
     printf("\n%s %d %f\n",e[i]->name,e[i]->id,e[i]->salary); 
    } 
} 
else 
{ 
    printf("\nEither reading error or partial content read\n"); 
} 
} 

int main() 
{ 
FILE *fp=NULL; 
char a='a'; 

do 
{ 
    printf("\nEnter w to write, r to read and e to exit\n"); 
    //scanf("%c",&a); 
    a=getche(); 

    switch(a) 
    { 
     case 'w': 
       fp=fopen("binary_ptr.exe","wb"); 
       if(fp==NULL) 
       { 
        printf("\nError opening file to write\n"); 
        exit(0); 
       } 
       write(fp); 
       fclose(fp); 
       break; 
     case 'r': 
       fp=fopen("binary_ptr.exe","rb"); 
       if(fp==NULL) 
       { 
        printf("\nError opening file to read\n"); 
        exit(0); 
       } 
       read(fp); 
       fclose(fp); 
       break; 
     case 'e': 
       exit(0); 
       break; 
     default: 
       printf("\nInvalid input\n"); 
       break; 
    } 
} 
while(1); 

return 0; 
} 

回答

2

在读/写如图所示的代码假定所有的结构被放置在存储器开始*e的连续区域。不是这种情况。

该代码没有定义struct的数组,但是指向后者的指针。动态分配的struct本身分散在整个内存中。

因为它代表的代码写入/读取超出*e[0]的界限调用未定义行为对所有MAX>1

要修复此循环周围fread()/fwrite()MAX时间为一个struct每个。

(必须指出这个问题明确地运行使用Valgrind内存检查编译后的代码,例如。)


由于旁注无关您的问题:read()write()是坏名一个拥有POSIX C标准已经使用的功能。

0

在读出功能,必须

if(fread(*e,sizeof(struct emp),MAX,f)==MAX) 

此读取MAX元件成阵列e。但是,e不是连续的数组。您正在使用

e[i]=malloc(sizeof(struct emp)); 
0

分别分配e你不能这样做,因为(fread(*e, sizeof(struct emp), MAX, f)您为EMP结构分配的内存不连续,如正确地指出,你有一个指针数组来emp结构,而不是一个数组emp结构。您需要单独读取每个emp

for (int i = 0; i < MAX; ++i){ 
    if (fread(e[i], sizeof(struct emp), 1, f) == sizeof(struct emp)){ 
     printf("\n%s %d %f\n", e[i]->name, e[i]->id, e[i]->salary); 
    } else { 
     ... 
    } 
} 

同样,当你写emp数据保存到文件,你需要做它分开过

for (int i = 0; i < MAX; ++i){ 
    check = fwrite(e[i], sizeof(struct emp), 1, f); 
    if (check != sizeof(struct emp)){ 
     ... 
    } else { 
    ... 
    } 
} 
相关问题