找了很多遍了,还是没找出错误的原因,求高手指点迷津!
运行一下代码,输入值《=80时,正常运行输出;而输入值大于80时,fopen打开出错!
想了很久,觉得可能是本人对fopen还不够了解~
//Program 12.4 Page 464
#define _STDC_WANT_LIB_EXT1_ 1
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<stdbool.h>
#include<string.h>
#define PER_LINE 8
#define MEM_PRIMES 80
struct
{
char *filename;
FILE *pfile;
unsigned long long primes[MEM_PRIMES];
size_t count;
}global={.filename=”myfile.bin”,.pfile=NULL,.primes={2ULL,3ULL,5ULL},.count=3};
bool is_prime(unsigned long long trial);
void list_primes(void);
void write_file(unsigned long long primes[],size_t n);
int main(void)
{
size_t total=0;
printf(“How many primes do you want to print out? “);
scanf_s(” %zd”,&total);
size_t num_primes=3;
unsigned long long trial=global.primes[2];
while(global.count<total)
{
trial+=2;
if(is_prime(trial))
{
if(num_primes<MEM_PRIMES-1)
{
global.primes[num_primes++]=trial;
global.count++;
}
else
{
global.primes[num_primes]=trial;
write_file(global.primes,MEM_PRIMES);
global.count++;
num_primes=0;
}
}
}
if(num_primes!=0)
write_file(global.primes,num_primes);
list_primes();
remove(global.filename);
return 0;
}
bool is_prime(unsigned long long trial)
{
size_t write_count=global.count/MEM_PRIMES;
size_t num_primes=global.count%MEM_PRIMES;
unsigned long long buf[MEM_PRIMES];
for(size_t i=0;i<num_primes;i++)
{
if(trial%global.primes[i]==0)
return false;
}
if(write_count!=0)
{
if(fopen_s(&global.pfile,global.filename,”rb”))
{
printf(“Error on opening %s. Program terminated!\n”,global.filename);
exit(1);
}
setvbuf(global.pfile,NULL,_IOFBF,BUFSIZ);
do
{
fread(buf,sizeof(unsigned long long),MEM_PRIMES,global.pfile);
for(size_t i=0;i<MEM_PRIMES;i++)
{
if(trial%buf[i]==0)
return false;
}
}while(!feof(global.pfile));
fclose(global.pfile);
global.pfile=NULL;
}
return true;
}
void write_file(unsigned long long primes[],size_t n)
{
if(fopen_s(&global.pfile,global.filename,”ab”))
{
printf(“Error on opening %s for writing. Program terminated!\n”,global.filename);
exit(1);
}
setvbuf(global.pfile,NULL,_IOFBF,BUFSIZ);
fwrite(global.primes,sizeof(unsigned long long),n,global.pfile);
fclose(global.pfile);
global.pfile=NULL;
}
void list_primes(void)
{
if(fopen_s(&global.pfile,global.filename,”rb”))
{
printf(“Error on opening %s. Program terminated!\n”,global.filename);
exit(1);
}
setvbuf(global.pfile,NULL,_IOFBF,BUFSIZ);
do
{
size_t n=fread(global.primes,sizeof(unsigned long long),PER_LINE,global.pfile);
for(size_t i=0;i<n;i++)
printf(“%5llu”,global.primes[i]);
printf(“\n”);
}while(!feof(global.pfile));
fclose(global.pfile);
global.pfile=NULL;
}
运行一下代码,输入值《=80时,正常运行输出;而输入值大于80时,fopen打开出错!
想了很久,觉得可能是本人对fopen还不够了解~
//Program 12.4 Page 464
#define _STDC_WANT_LIB_EXT1_ 1
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<stdbool.h>
#include<string.h>
#define PER_LINE 8
#define MEM_PRIMES 80
struct
{
char *filename;
FILE *pfile;
unsigned long long primes[MEM_PRIMES];
size_t count;
}global={.filename=”myfile.bin”,.pfile=NULL,.primes={2ULL,3ULL,5ULL},.count=3};
bool is_prime(unsigned long long trial);
void list_primes(void);
void write_file(unsigned long long primes[],size_t n);
int main(void)
{
size_t total=0;
printf(“How many primes do you want to print out? “);
scanf_s(” %zd”,&total);
size_t num_primes=3;
unsigned long long trial=global.primes[2];
while(global.count<total)
{
trial+=2;
if(is_prime(trial))
{
if(num_primes<MEM_PRIMES-1)
{
global.primes[num_primes++]=trial;
global.count++;
}
else
{
global.primes[num_primes]=trial;
write_file(global.primes,MEM_PRIMES);
global.count++;
num_primes=0;
}
}
}
if(num_primes!=0)
write_file(global.primes,num_primes);
list_primes();
remove(global.filename);
return 0;
}
bool is_prime(unsigned long long trial)
{
size_t write_count=global.count/MEM_PRIMES;
size_t num_primes=global.count%MEM_PRIMES;
unsigned long long buf[MEM_PRIMES];
for(size_t i=0;i<num_primes;i++)
{
if(trial%global.primes[i]==0)
return false;
}
if(write_count!=0)
{
if(fopen_s(&global.pfile,global.filename,”rb”))
{
printf(“Error on opening %s. Program terminated!\n”,global.filename);
exit(1);
}
setvbuf(global.pfile,NULL,_IOFBF,BUFSIZ);
do
{
fread(buf,sizeof(unsigned long long),MEM_PRIMES,global.pfile);
for(size_t i=0;i<MEM_PRIMES;i++)
{
if(trial%buf[i]==0)
return false;
}
}while(!feof(global.pfile));
fclose(global.pfile);
global.pfile=NULL;
}
return true;
}
void write_file(unsigned long long primes[],size_t n)
{
if(fopen_s(&global.pfile,global.filename,”ab”))
{
printf(“Error on opening %s for writing. Program terminated!\n”,global.filename);
exit(1);
}
setvbuf(global.pfile,NULL,_IOFBF,BUFSIZ);
fwrite(global.primes,sizeof(unsigned long long),n,global.pfile);
fclose(global.pfile);
global.pfile=NULL;
}
void list_primes(void)
{
if(fopen_s(&global.pfile,global.filename,”rb”))
{
printf(“Error on opening %s. Program terminated!\n”,global.filename);
exit(1);
}
setvbuf(global.pfile,NULL,_IOFBF,BUFSIZ);
do
{
size_t n=fread(global.primes,sizeof(unsigned long long),PER_LINE,global.pfile);
for(size_t i=0;i<n;i++)
printf(“%5llu”,global.primes[i]);
printf(“\n”);
}while(!feof(global.pfile));
fclose(global.pfile);
global.pfile=NULL;
}
解决方案
20
崩溃的时候在弹出的对话框按相应按钮进入调试,按Alt+7键查看Call Stack即“调用堆栈”里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处,看不懂时双击下一行,直到能看懂为止。
判断能否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。假如该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。
判断能否越界访问,可以在数组的最后一个元素之后对应的地址处设置数据读写断点。假如该地址对应其它变量干扰判断,可将数组多声明一个元素,并设置数据读写断点在该多出元素对应的地址上。
#include <time.h> #include <stdlib.h> #include <windows.h> int main() { int a,b[11];//本来是b[10],为判断哪句越界,故意声明为b[11] srand((unsigned int)time(NULL));//按两次F11,等黄色右箭头指向本行时,调试、新建断点、新建数据断点,地址:&b[10],字节计数:4,确定。 while (1) {//按F5,会停在下面某句,此时a的值为10,b[10]已经被修改为对应0..4之一。 b[(a=rand()%11)]=0; Sleep(100); b[(a=rand()%11)]=1; Sleep(100); b[(a=rand()%11)]=2; Sleep(100); b[(a=rand()%11)]=3; Sleep(100); b[(a=rand()%11)]=4; Sleep(100); } return 0; }
30
不要凭空想是什么原因,
Return value
1) If successful, returns a pointer to the new file stream. The stream is fully buffered unless filename refers to an interactive device. On error, returns a null pointer. POSIX requires that errno is set in this case.
检查errno的值来判断是什么原因
http://en.cppreference.com/w/c/io/fopen
Return value
1) If successful, returns a pointer to the new file stream. The stream is fully buffered unless filename refers to an interactive device. On error, returns a null pointer. POSIX requires that errno is set in this case.
检查errno的值来判断是什么原因
http://en.cppreference.com/w/c/io/fopen
15
确实,像这种问题,出错后,检查下errno就知道原因了,perror () 或 strerror() 打印一下。明显问题是fopen的mode不对,
“rb” –> “ab”
“rb” –> “ab”