由于某种原因退出while循环后,数组中的值发生了变化,但我不是原因。在循环内部,值是正确的,它们通常存储在数组(a)内。这是在c!
int * readFile()
{
char file_name[50];
printf("Enter the name of the file to open:\n");
scanf("%s",file_name);
FILE *fp;
fp = fopen(file_name,"r");
if(fp == NULL )
{
printf("Sorry but the File you entered cannot be opened\n");
int *b;
b[0] = -1;
return b;
}
int *a;
int j=0;
long int value=0;
while (fscanf(fp,"%d",&value)!=EOF) {
if((a =malloc(sizeof(long int))) == NULL)
printf("not enough memory\n");
a[j]=value;
j++;
}
printf("%d %d %d\n",a[0],a[1],a[2]);
int i=0;
for(i=0; i<j;i++)
{
printf("array[%d] = %d\n",i,a[i]);
}
fclose(fp);
return a;
}
非常感谢任何帮助!
答案 0 :(得分:0)
执行if((a =malloc(sizeof(long int))) == NULL)
时,您只为单个long int(大小为32位)分配足够的内存,但是您需要为计划存储的每个int分配内存。因为malloc分配了一块内存,所以您需要知道您计划存储多少个int。如果您不介意开销,可以通过正在读取的文件进行初步运行并计算您将读取的整数(基本上是您的j变量),然后就可以了
a =malloc( intCounter * sizeof(long int))) == NULL
,其中intCounter将是文件(j)中的整数总数。
另一种选择是使用链接列表(它接近你想要做的事情),你可以动态地为每个int分配内存,但是你需要将指针信息存储到下一个节点中。阵列。
while循环中的malloc调用将覆盖存储在Int的单个分配中的数据。例如,如果您从文本文件中读取1 2 3,它将在a,malloc不同的内存地址中存储1,存储2,malloc,另一个内存地址和存储3.导致打印0,0,3。
答案 1 :(得分:0)
您在代码中使用了int
和long int
混合。你需要建立一致的类型;对于我的回答我和int
一起走了。 (您可以轻松浏览并将所有int
更改为long
,只要您还将fscanf
格式字符串更改为%ld
)。
目前,您每次在循环中分配一个long int
的新块。除了从先前的循环迭代中泄漏内存之外,您还可以访问此界限。此外,当malloc失败时,您打印一条消息并继续前进!
相反,您需要分配一个包含多个整数的块。一种方法是使用realloc
函数使现有分配更大。
此外,在检查fscanf
的返回值时,您应该在此处检查== 1
。如果他们输入了一些字母但没有触发EOF条件,它将返回0
,因此您的程序将永远继续。
以下是该循环的样子:
int *a = NULL;
size_t j = 0;
while ( fscanf(fp,"%d",&value) == 1 )
{
int *ptr = realloc( a, (j+1) * sizeof *a );
if ( !ptr )
{
printf("not enough memory\n");
break;
}
a = ptr;
a[j]=value;
j++;
}
通过为新分配使用单独的变量ptr
,我们可以从内存不足的情况中恢复(程序可以继续使用到目前为止输入的整数的数量)。
如果您打算通过立即退出程序来处理内存不足(例如通过调用exit(EXIT_FAILURE);
而不是break;
,那么您可以使用a = realloc( a,
等缩短代码而不是ptr
。
早期的代码int *b; b[0] = -1;
有一个问题:b
并不指向任何地方,但您通过它进行了书写。
此功能存在设计问题,因为呼叫者无法知道j
是什么。对此的一个解决方案是始终将-1
放在输入的末尾(这个想法被称为&#34; sentinel值&#34; - 并且记得为它分配空间);另一种选择是拥有一个&#34; out&#34;函数的参数。