我如何使fread在C语言中正常工作?它用零填充我的动态数组

问题描述 投票:-1回答:1

我正在编写一个c程序,该程序需要读取一个二进制文件,将其放入结构数组中,然后对该数组进行排序。结构:

#define NCHAR 64

typedef
    struct data_
    {
        char country[NCHAR];
        long int population;
        float world_share;
    }
data;

所有这些都发生在一个单独的函数中,该函数使用freed()从文件中获取数组。并且此功能实际上不起作用。我希望看到的是:

CountryA        100    10%
CountryB        200    20%

我实际上得到的是:

0        0    0%
0        0    0%

您能看看我做错了吗?我试图重写我的代码,可以并且正在寻找fread()函数的使用,但似乎我使用的是正确的。

void SortAndDisplayASC( void )//main
{
    FILE * worldData;
    worldData = fopen("world.dat", "rb");
    if(worldData == NULL)
    {
        printf("NO FILE CAN BE ACSESSED\n");
        exit(1);
    }
    long size = fsize(worldData);
    int ammount = size / sizeof(data);
    data * countries;
    countries = (data *) malloc(size);
    fread(countries, sizeof(data), ammount, worldData); //PROBLEM HERE!
    sortByPopulation(countries, ammount);
    for(int i = 0; i < ammount;  i ++)
    {
        PrintData(countries[i]);
    }
    free(countries);
    fclose(worldData);
}

如果您愿意帮助我,我将分享整个代码。

c fread
1个回答
0
投票

缺少完整的代码和数据:我重新创建了程序的缺失部分,并在代码中添加了一些注释以简化代码审查:

  • 从用户处接收样本数据(5条记录,],>
  • 将其写入二进制文件(world.dat),
  • 从文件中读取数据,
  • 人口数据并列出。
  • 它可以在我的机器(gcc-Wall)上编译并很好地运行,您可以遍历并与您的代码进行比较;希望对您有帮助。

下面是排序后程序的输出:

Sort is completed successfully using bubble-sorting technique!
Country: D - Population: 5 - World Share: 2 %
Country: C - Population: 20 - World Share: 8 %
Country: A - Population: 50 - World Share: 20 %
Country: E - Population: 80 - World Share: 31 %
Country: B - Population: 100 - World Share: 39 %

请注意,如果您的数据文件不能正确反映结构,则不会产生正确的数据。

/** by: moemen.ahmed 
 * date: 16 May 20
 * reference to stackoverflow: https://stackoverflow.com/questions/61830512/how-can-i-make-fread-work-properly-in-c-it-fills-my-dynamic-array-with-zeroes 
 * purpose: collect and store countires population input in a binary file, then re-read the file, and sort it by population.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NCHAR 64

// define the main Country struct
typedef
    struct Country_
    {
        char country[NCHAR];
        long int population;
        float world_share;
    }
Country;

// store countries count in a global variable
int count = 0;
// store total population in a global variable
long int totalPopulation = 0;
// declare a global pointer that will point to the start of data-blocks

// functions declaration
// receives the user input and store it in memory
void addCountry();
// update the world_share% in each of the structs in memory
void updateWorldShare();
// list countries data from memory
void listCountries();
// write the list of countries to the file world.dat
void writeCountries(); 
// read the data from the file to memory
void readCountries ();
// calculate the number of records in the file; update the global variable 'count'
int fsize(FILE* file); 
// sort the records in the memory
void sortCountriesByPopulation();

// main function
int main(int argc, char **argv) {
    int x = 0;
    while (x < 5) {
        addCountry();
        x += 1;
    }
    updateWorldShare();
    listCountries();
    writeCountries();
    // let us reset the data, so everything comes from reading the file afterwards.
    free(countries);
    totalPopulation = 0;
    count = 0;
    // read the binary file
    readCountries();
    sortCountriesByPopulation();
    listCountries();
    free(countries);
    return 0;
}

void listCountries(){
    // int count = getCountriesCount();
    Country* currCountry;
    for (int i = 0; i < count; i++) 
    {
        currCountry = countries + (i * sizeof(Country));
        printf("Country: %s - Population: %ld - World Share: %0.00f %%\n", currCountry->country, (long int) currCountry->population, (float) currCountry->world_share * 100);
    }
    return;
}


void addCountry()
{
    Country new;
    printf("Enter Country Name.");
    scanf("%s", new.country);
    printf("Enter Population.");
    scanf("%ld", &new.population); 
    // ignore calculating world-share% during input.
    new.world_share = 0.0;
    countries = (Country *) realloc( countries, (count + 1) * sizeof(Country));
    *(countries + (count ) * sizeof(Country)) = new;
    // update the goabl count and totalPopulation
    totalPopulation += new.population;
    count += 1;
    return ;
}

void updateWorldShare(long int population){
    printf("... updadting world share %% \n");
    printf("... total population : %ld\n", (long int) totalPopulation);
    Country* currCountry;
    for (int i = 0; i < count; i++) {
        currCountry = countries + (i * sizeof(Country));
        currCountry->world_share = ((float) currCountry->population )/ ((float) totalPopulation);
    }
    return;
}

void updateTotalPopulation(){
    printf("... updadting TotalPopulation\n");
    totalPopulation = 0;
    Country* currCountry;
    for (int i = 0; i < count; i++) {
        currCountry = countries + (i * sizeof(Country));
        totalPopulation += currCountry->population; 
    }
    printf("... total population : %ld\n", (long int) totalPopulation);
    return;
}

void sortCountriesByPopulation(){
    printf("... sorting countries by population, Count: %d\n", count);
    Country *xCountry, *yCountry;
    for (int i = 0; i < (count - 1); i++) {
        for (int j = 0; j < (count - 1 - i ); j++) {
            xCountry = countries + (j * sizeof(Country));
            yCountry = countries + ((j+1) * sizeof(Country));
            if (xCountry->population > yCountry->population){
                // do a swap
                Country tempCountry; 
                tempCountry = *xCountry;
                *xCountry = *yCountry;
                *yCountry = tempCountry;
            }
        }
    }
    printf("Sort is completed successfully using bubble-sorting technique!\n");

    return;
}

void readCountries(void)//main
{
     printf("reading ...... \n");
     FILE * worldData;
     worldData = fopen("world.dat", "rb");
     if(worldData == NULL)
     {
         printf("NO FILE CAN BE ACSESSED\n");
         exit(1);
     }
     long size = fsize(worldData);
     count = size / sizeof(Country);
     Country * countries;
     countries = (Country *) malloc(size);
     fread(countries, sizeof(Country), count, worldData); 
     fclose(worldData);
     updateTotalPopulation();
     return;
}

int fsize(FILE* file) {
    fseek(file, 0L, SEEK_END);
    int size = ftell(file);
    fseek(file, 0L, SEEK_SET);
    return size;
}


void writeCountries( void) 
{
     FILE * worldData;
     worldData = fopen("world.dat", "wb");
     fwrite(countries, sizeof(Country), count, worldData); 
     fclose(worldData);
 }
© www.soinside.com 2019 - 2024. All rights reserved.