我正在编写一个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);
}
如果您愿意帮助我,我将分享整个代码。
缺少完整的代码和数据:我重新创建了程序的缺失部分,并在代码中添加了一些注释以简化代码审查:
它可以在我的机器(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);
}