C语言的可移植性问题
我尝试编写一个程序,将结构元素写入二进制文件,然后将第一个文件中的唯一元素写入另一个二进制文件。我用gcc编译它,它工作得很好,但是用MinGW,程序在尝试打开和创建第二个文件时冻结。您知道问题出在哪里吗?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct element{
char name[80];
int p;
}ELEM;
void clear_stdin()
{
char str[255];
fgets(str,255,stdin);
}
int create()
{
FILE *f;
int d=0;
int c;
int n=0;
ELEM s;
f=fopen("file.bin","wb");
if(f==NULL)
{
printf("create(): Could not open file.bin for read\n");
return;
}
do{
printf("Add elements to file?:\n1 - yes\n2 - no\n");
scanf("%d",&c);
if (c==1)
{
printf("Name=");
clear_stdin();
fgets(s.name,80,stdin);
printf("P=");
scanf("%d",&s.p);
fwrite(&s,sizeof(ELEM),1,f);
n++;
}
else
d=1;
} while(d==0);
fclose(f);
return n;
}
void show(int n)
{
FILE *f;
ELEM s;
int i=0;
if(n==0)
return;
f=fopen("file.bin","rb");
while(i<n)
{
fread(&s,sizeof(ELEM),1,f);
puts(s.name);
printf("\t%d\n",s.p);
i++;
}
fclose(f);
}
int add(int n)
{
FILE *f;
int d=0;
int c;
ELEM s;
f=fopen("file.bin","ab");
if(f==NULL)
{
printf("add(): Could not open file.bin for append\n");
return;
}
do{
printf("Add elements to file?:\n1 - yes\n2 - no\n");
scanf("%d",&c);
if (c==1)
{
printf("Name=");
clear_stdin();
fgets(s.name,80,stdin);
printf("P=");
scanf("%d",&s.p);
fwrite(&s,sizeof(ELEM),1,f);
n++;
}
else
d=1;
} while(d==0);
fclose(f);
return n;
}
void func(int n)
{
FILE *f,*g;
ELEM v[20],w;
int i=0,j,k,x=0,s,gn=0,test;
f=fopen("file.bin","rb");
g=fopen("aux.bin","wb");
if((g==NULL)||(f==NULL))
{
if(g==NULL)
printf("function() : Could not open aux.bin for write\n");
if(f==NULL)
printf("function() : Could not open file.bin for read\n");
return;
}
i=0;
while(i<n)
{
fread(&v[i],sizeof(ELEM),1,f);
i++;
}
for(j=0;j<n;j++)
{
for(k=j+1;k<n;k++)
{
if(v[j].p==v[k].p)
x=1;
}
if(x==0)
{
s=strcmp(v[j].name,v[k].name);
if(s!=0)
{
fwrite(&v[j],sizeof(ELEM),1,g);
fread(&w,sizeof(ELEM),1,g);
gn++;
}
}
x=0;
}
test=fclose(g);
if(test!=0)
printf("function() : failed to closed file g\n");
test=fclose(f);
if(test!=0)
printf("function() : failed to closed file f\n");
g=fopen("aux.bin","rb");
if(g==NULL)
{
printf("function() : Could not open aux.bin for read\n");
return;
}
if(gn==0)
return;
i=0;
while(i<gn)
{
fread(&w,sizeof(ELEM),1,g);
puts(w.name);
printf("\t%d\n",w.p);
i++;
}
fclose(g);
}
int main()
{
int k=0,r,n;
do{
printf("1 - create file\n2 - add elements to file\n3 - show elements\n4 - put unique elements in another file\n5 - exit program\n");
scanf("%d",&r);
switch(r)
{
case 1 : n=create(); break;
case 2 : n=add(n); break;
case 3 : show(n); break;
case 4 : func(n); break;
case 5 : k=1; break;
default : printf("Command unrecognized!\n");
}
} while(k==0);
return 0;
}
编辑: 函数 func() 是唯一的问题。
编辑:是的,我可以在 gdb 下运行它。
编辑: 在这两种情况下,sizeof(ELEM)=84 offsetof(ELEM,p)=80。
I tried to make a program that writes struct elements to binary file and then writes the unique elements from the first file to another binary file. I compiled it with gcc and it works very good, but with MinGW the program freezes when it tries to open and create the second file. Do you have any idea where is the problem?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct element{
char name[80];
int p;
}ELEM;
void clear_stdin()
{
char str[255];
fgets(str,255,stdin);
}
int create()
{
FILE *f;
int d=0;
int c;
int n=0;
ELEM s;
f=fopen("file.bin","wb");
if(f==NULL)
{
printf("create(): Could not open file.bin for read\n");
return;
}
do{
printf("Add elements to file?:\n1 - yes\n2 - no\n");
scanf("%d",&c);
if (c==1)
{
printf("Name=");
clear_stdin();
fgets(s.name,80,stdin);
printf("P=");
scanf("%d",&s.p);
fwrite(&s,sizeof(ELEM),1,f);
n++;
}
else
d=1;
} while(d==0);
fclose(f);
return n;
}
void show(int n)
{
FILE *f;
ELEM s;
int i=0;
if(n==0)
return;
f=fopen("file.bin","rb");
while(i<n)
{
fread(&s,sizeof(ELEM),1,f);
puts(s.name);
printf("\t%d\n",s.p);
i++;
}
fclose(f);
}
int add(int n)
{
FILE *f;
int d=0;
int c;
ELEM s;
f=fopen("file.bin","ab");
if(f==NULL)
{
printf("add(): Could not open file.bin for append\n");
return;
}
do{
printf("Add elements to file?:\n1 - yes\n2 - no\n");
scanf("%d",&c);
if (c==1)
{
printf("Name=");
clear_stdin();
fgets(s.name,80,stdin);
printf("P=");
scanf("%d",&s.p);
fwrite(&s,sizeof(ELEM),1,f);
n++;
}
else
d=1;
} while(d==0);
fclose(f);
return n;
}
void func(int n)
{
FILE *f,*g;
ELEM v[20],w;
int i=0,j,k,x=0,s,gn=0,test;
f=fopen("file.bin","rb");
g=fopen("aux.bin","wb");
if((g==NULL)||(f==NULL))
{
if(g==NULL)
printf("function() : Could not open aux.bin for write\n");
if(f==NULL)
printf("function() : Could not open file.bin for read\n");
return;
}
i=0;
while(i<n)
{
fread(&v[i],sizeof(ELEM),1,f);
i++;
}
for(j=0;j<n;j++)
{
for(k=j+1;k<n;k++)
{
if(v[j].p==v[k].p)
x=1;
}
if(x==0)
{
s=strcmp(v[j].name,v[k].name);
if(s!=0)
{
fwrite(&v[j],sizeof(ELEM),1,g);
fread(&w,sizeof(ELEM),1,g);
gn++;
}
}
x=0;
}
test=fclose(g);
if(test!=0)
printf("function() : failed to closed file g\n");
test=fclose(f);
if(test!=0)
printf("function() : failed to closed file f\n");
g=fopen("aux.bin","rb");
if(g==NULL)
{
printf("function() : Could not open aux.bin for read\n");
return;
}
if(gn==0)
return;
i=0;
while(i<gn)
{
fread(&w,sizeof(ELEM),1,g);
puts(w.name);
printf("\t%d\n",w.p);
i++;
}
fclose(g);
}
int main()
{
int k=0,r,n;
do{
printf("1 - create file\n2 - add elements to file\n3 - show elements\n4 - put unique elements in another file\n5 - exit program\n");
scanf("%d",&r);
switch(r)
{
case 1 : n=create(); break;
case 2 : n=add(n); break;
case 3 : show(n); break;
case 4 : func(n); break;
case 5 : k=1; break;
default : printf("Command unrecognized!\n");
}
} while(k==0);
return 0;
}
EDIT:
function func() is the only problem.
EDIT: Yes I can run it under gdb.
EDIT:
sizeof(ELEM)=84 offsetof(ELEM,p)=80 in both cases.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
哇,伙计们,你不会猜到这个:
aux.bin
,实际上任何aux.*
都是 Windows 上的保留文件名!这就是为什么它需要永远!看一下这里,这样您就不会意外选择另一个保留的文件名:Windows 文件名规范(在页面中搜索“aux”)
Wow guys you will not guess this:
aux.bin
, actually anythingaux.*
is a reserved filename on Windows! That's why it is taking forever! Take a look here so you dont accidentally choose another reserved filename:windows file name specification (search the page for 'aux')