我正在编写一个程序,该程序使用动态分配的数组存储库存(三个数字数组),并将这些数组存储在名为“ inventory.txt”的二进制文件中。我遇到的问题是,当我打印出数组时,我的数组中确实出现了奇怪的数字。程序错误地读取了二进制文件,数组的大小被读取到程序中,因为显示了正确数量的元素,并且数字在多次迭代中没有变化。如何正确读取数字,以便程序显示正确的数字?
有两个程序,第一个创建一个二进制文件“ inventory.txt”,并将三个变量的零件号,数量和价格连续放入动态分配的数组中,该数组随每个条目的增加而增加,并在用户输入0时结束数字(只需输入一个0)。第二个程序仅读取存储在二进制文件“ inventory.txt”中的数组和数组大小,并打印“ i”行数量以及其中存储的数字。这是两个程序。
#include <stdio.h>
#include <stdlib.h>
//THIS IS FIRST PROGRAM THAT STORES THE ARRAY BASED ON USER INPUT
int main(){
printf("This program stores an invetory: ");//declarations
int i=0, holdr, k=0;
int *pn, *q;
float *p;
q=malloc(sizeof(int));
pn=malloc(sizeof(int)); //allocate space
p=malloc(sizeof(float));
FILE *fp;
fp=fopen("inventory.txt","w+b"); //open file
while(holdr!=0){
pn=realloc(pn, (i+1) * sizeof(int)); //read data into the three arrays
q=realloc(q, (i+1) * sizeof(int));
p=realloc(p, (i+1) * sizeof(float));
printf("Please enter item data (part number, quantity, price): ");
scanf("%d,%d,%f",&pn[i],&q[i],&p[i]);
holdr=pn[i];
i++;
k++;
}
fwrite(&i,sizeof(int),1,fp); //write arrays to inventory.txt(binary)
fwrite(&pn,sizeof(int),k,fp);
fwrite(&q,sizeof(int),k,fp);
fwrite(&p,sizeof(float),k,fp);
printf("Thank you. Inventory stored in inventory.txt. \n");
fp=fopen("inventory.txt","r+b"); //Check to see if file is correct by printing from the file inside the same program.
if (fp == NULL){
printf("nah");
exit(EXIT_FAILURE);
}
for(i=0;i<k;i++){
fread(&pn,sizeof(int),k,fp); //THIS DISPLAYS THE ARRAYS CORRECTLY AS ENTERED
printf("%d\t" , pn[i]);
fread(&q,sizeof(int),k,fp);
printf("%d\t", q[i]);
fread(&p,sizeof(int),k,fp);
printf("%f\n", p[i]);}
fclose(fp);
return 0;
}
然后...
#include <stdio.h>
#include <stdlib.h>
//THE SECOND FILE THAT PRINTS OUT THE ARRAYS FROM THE FIRST PROGRAM
int main(){
FILE *fp = fopen("inventory.txt","r+b"); //declarations
if (fp == NULL){ //check file
printf("nah");
exit(EXIT_FAILURE);
}
int i;
fread(&i,sizeof(int),1,fp); //get size of arrays from "i" in the other program, THIS PART WORKS
int l,k;
int *pn, *q;
float *p;
q = (int *)malloc(i * sizeof(int)); // TODO - check malloc() OK
pn = (int *)malloc(i * sizeof(int)); // TODO - check malloc() OK
p = (float *)malloc(i * sizeof(float)); // TODO - check malloc() OK
fread( q, sizeof( int ), i, fp ); //read arrays in file into program
fread( p, sizeof( float ), i, fp );
fread( pn, sizeof( int ), i, fp );
printf("Below are the items in your inventory.\nPart#\tQuantity\tPrice\n");
for(l=0;l<i;l++){ //THIS DISPLAYS WEIRD ASS NUMBERS
printf("%d\t" , pn[l]);
printf("%d\t", q[l]);
printf("%f\n", p[l]);}
rewind(fp);
fclose(fp);
return 0;}
答案 0 :(得分:2)
您的程序存在多个问题。首先,要使程序完全运行,您需要将holdr
定义为非零值。
int i=0, holdr=1, k=0;
调试文件写入/读取问题的第一步是检查程序写入的文件。在对输出文件进行十六进制转储时,我看到该文件仅包含垃圾值,因此您的写入程序本身已损坏。有了这些信息,如果我们看一下您的代码,您的程序之所以会写出垃圾值的原因是因为在fwrite
fwrite(&i,sizeof(int),1,fp); //this is okay, i is an int, &i is int*
fwrite(&pn,sizeof(int),k,fp); //this is not okay, pn is int*, &pn is int**
基本上,您是在将阵列的地址而不是阵列的内容写入文件。因此,在回读时,您将获得数组的地址-这似乎是垃圾。
除了解决程序中的许多其他问题外,从数组的fwrite中删除&
,然后程序将写入正确的值,因此您的读取程序也可以读取正确的值。
fwrite(pn,sizeof(int),k,fp); //this is the right usage, pn is int*
答案 1 :(得分:0)
您没有初始化int holdr
。因此while(holdr!=0)
是未定义的行为。无法确定该变量的含义,因此您的循环可能开始也可能不会开始。
使用realloc
分配内存后,将立即出现对malloc
的调用,但是没有测试来确定是否需要额外的空间。通常,人们会写类似if (not_enough_space) realloc(something)
的文字。您的代码(假设它甚至超过了前面提到的未定义行为),将只为pn和q分配单个整数的空间,为p分配单个浮点的空间,因此首先不需要malloc。>
您说您的结果不会改变...这是由于以下事实:不断地重新分配数组并将值存储到它们,而无需将结果写入文件。它只是无限循环,要求用户输入,直到pn[0]
恰好变为0。
在第二个源文件中,int i
必须在使用前初始化。
没有理由强制转换malloc的结果。指向void的指针基本上是无类型的内存地址。