任务是从文件中读取地图然后显示它。二进制文件以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);
}
}
}
答案 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);