fread无法从文件

时间:2018-05-17 15:25:02

标签: c struct

任务是从文件中读取地图然后显示它。二进制文件以2个浮点数开头,并继续使用以下格式的对象:

struct Node {
float height;
int terrainType;
float visitsCount;
struct Node *next;
}Node;

执行阅读的功能:

void showMapTerrain(struct Node Node)
{
FILE *fp;
if ((fp = fopen("map.bin", "rb")) == NULL) {
    puts("Unable to open file.");
    exit(7);
}
float mapLenght, alt;
    if (fread(&mapLenght, sizeof(float), 1, fp) != 1) {
        puts("Unable to read from file.");
        exit(18);
    }
    if (fread(&alt, sizeof(float), 1, fp) != 1) {
        puts("Unable to read from file.");
        exit(20);
    }
/*Idea with this is to get the 2 floats out of the way so I can start reading the objects with a single fread.*/

char *mapTerrain = (char *)calloc(mapLenght, sizeof(char));

while (1) {
    if (fread(&Node, sizeof(struct Node), 1, fp) != 1) {
//But this bit right here fails, it reads 0 objects.
        printf("fread: %d\n", fread(&Node, sizeof(struct Node), 1, fp));
        puts("Unable to read from file.");
        exit(30);
    }
*mapTerrain = Node.terrainType;
}
puts("Terrain type map: ");
while (*mapTerrain) {
    printf("[%c]", *mapTerrain);
}
free(mapTerrain);
}

2个浮点数仅在开头,所以它们在循环之外,读取对象。我很确定fread的语法是正确的,我不清楚问题是什么。 此外,不需要在此函数中创建链接列表,我们创建一个数字数组(范围1-4,因此char *),然后显示它。 编辑:执行写作的功能:

    void addToFile(struct Node Node)
    {
        FILE *fp;
        float mapLenght, alt;
        if ((fp = fopen("map.bin", "rb")) == NULL) {
            if ((fp = fopen("map.bin", "wb")) == NULL) {
//2 fopens to check if the file exists. If it doesn't, the user has to input the //2 floats in the beginning. Otherwise we skip straight to adding objects in the //file
                puts("Unable to open the file.");
                exit(7);
            }
            puts("How long is the map?");
            scanf("%f", &mapLenght);
            if (fwrite(&mapLenght, sizeof(float), 1, fp) != 1) {
                puts("Unable to write to file.");
                exit(6);
            }
            puts("What's the map's altitude?");
            scanf("%f", &alt);
            if (fwrite(&alt, sizeof(float), 1, fp) != 1) {
                puts("Unable to write to file.");
            }
            fclose(fp);
        }
        else {
            fclose(fp);
        }
        if ((fp = fopen("map.bin", "ab")) == NULL){
            puts("Unable to open file for further writing.");
            exit(7);
    }
        int c = 0;
        while (1) {
            puts("Inputting data for individual square meters of the map:");
            printf("How high is square meter %d?", ++c);
            puts("('-1' to stop.)");
            scanf("%f", &Node.height);
            if (Node.height == -1) {
                system("cls");
                puts("You've decided to stop adding data.");
                break;
            }
            printf("What's the terrain type of square meter %d?\n", c);
            puts("Values allowed: ");
            puts("0 - flora");
            puts("1 - waste");
            puts("2 - water");
            puts("3 - road");
            puts("4 - building");
            Node.terrainType = 7;
            while (1) {
                scanf("%d", &Node.terrainType);
                if (Node.terrainType < 0 || Node.terrainType>4) {
                    puts("Invalid data.");
                }
                else {
                    break;
                }
            }
            printf("What's the daily visit count for square meter %d?", c);
            scanf("%f", &Node.visitsCount);
            if (fwrite(&Node, sizeof(Node), 1, fp) != 1) {
//Unlike the other function, everything here works properly, even this fwrite
                puts("Error writing data to file.");
                exit(6);
            }
        }
    }

1 个答案:

答案 0 :(得分:1)

道歉,但我犯了一个非常愚蠢的错误。 fread正好读取对象,当它到达EOF时返回0。我假设它在第一次迭代时返回0。修复方法如下:

    int *mapTerrain = (int *)calloc(mapLenght, sizeof(int));
    int i = 0;
    while (1) {
        if (fread(&Node, sizeof(struct Node), 1, fp) != 1) {
            break;
        }
        mapTerrain[i] = Node.terrainType;
        i++;
    }
    puts("Map by terrain type: ");
    int n;
    for (n = 0; n < i; n++) {
        printf("[%d]", mapTerrain[n]);
    }
    puts("");
    free(mapTerrain);