C语言中的可移植性问题

4

我尝试编写一个程序,将结构体元素写入二进制文件,然后将第一个文件中的唯一元素写入另一个二进制文件。我使用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下运行它。

编辑: ELEM的大小为84,ELEM中p的偏移量在两种情况下都是80。


3
能不能把代码缩短一点?这么多代码让人看起来有些吃力。 - StilesCrisis
1
你需要提供一个简单的示例,最好是非交互式的,以展示问题。很有可能,在你有值得发布的示例之前,你就会弄清楚发生了什么。 - MK.
今天为什么结构序列化问题似乎每半小时就会出现一次? - Kerrek SB
程序在哪个地方卡住了?你能在gdb下运行它吗? - sergio
1个回答

2

哇,伙计们,你们肯定猜不到:在Windows系统中,aux.bin和任何以aux.*形式命名的文件都是保留文件名!这就是为什么它需要很长时间的原因!请查看这里,以免意外选择其他保留的文件名:windows file name specification(在页面上搜索“aux”)


这同样适用于CON、LPT1等。几年前在生产系统中我就是通过艰难的方式发现了这一点。 - Joe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接