在C中对结构数组进行排序

0 c arrays sorting struct

我们在课堂上给出了一个任务,对结构数组进行排序.在分配完成后,我们讨论了使用数组指针进行排序,因为它比大多数人的方式更有效.

我决定尝试这样做,但是我遇到了一些我无法解决的问题.

http://pastebin.com/Cs3y39yu

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>

typedef struct stage2{//standard dec of the struct field
     char need;
         double ring;
         char fight[8];
         int32_t uncle;
         char game;
         double war;
         int8_t train;
         uint32_t beds;
         float crook;
         int32_t feast;
         int32_t rabbits;
         int32_t chin;
         int8_t ground;
         char veil;
         uint32_t flowers;
         int8_t adjustment;
         int16_t pets;
} stage2;

void usage(){//usage method to handle areas
        fprintf(stderr,"File not found\n");//prints to stderr
        exit(1);//exits the program
}

int needS(const void *v1, const void *v2)
{
    const stage2 *p1 = v1;
    const stage2 *p2 = v2;
        printf("%c %c \n",p1->need,p2->need);
    return 0;
}


int main(int argc, char** argv){
        if(argc != 3){//checks for a input files, only 1
          usage();//if not runs usage
  }
  int structSize = 60;//size of structs in bytes, sizeof() doesnt return correct val
  char* fileName = argv[1];  //pull input filename
  FILE *file = fopen(fileName, "r");//opens in read mode
  fseek(file, 0, SEEK_END);  //goes to end of file
  long fileSize = ftell(file);  //saves filesize
  char *vals = malloc(fileSize);  //allocates the correct size for array based on its filesize
  fseek(file, 0, SEEK_SET);  //returns to start of file
  fread(vals, 1, fileSize, file);  //reads the file into char array vals
  fclose(file); //closes file
  int structAmount = fileSize/structSize; //determines amount of structs we need
  stage2 mainArray[structAmount]; //makes array of structs correct size


  int j;//loop variables
  int i;


  printf("need, ring, fight, uncle, game, war, train, beds, crook, feast, rabbits, chin, ground, veil, flowers, adjustment, pets\n");//prints our struct names

  for(i = 0; i < structAmount; i ++){//initialises the array vals
        mainArray[i].need = *(&vals[0+(i*60)]);
        mainArray[i].ring = *((double *)&vals[1+(i*60)]);
        for(j = 0;j<9;j++){
          mainArray[i].fight[j] = *(&vals[j+9+(i*60)]);
        }
        mainArray[i].uncle = *((int32_t *)&vals[17+(i*60)]);
        mainArray[i].game = *(&vals[21+(i*60)]);
        mainArray[i].war = *((double *)&vals[22+(i*60)]);
        mainArray[i].train = *((int8_t *)&vals[30+(i*60)]);
        mainArray[i].beds = *((uint32_t *)&vals[31+(i*60)]);   
        mainArray[i].crook = *((float *)&vals[35+(i*60)]);
        mainArray[i].feast = *((int32_t *)&vals[39+(i*60)]);
        mainArray[i].rabbits = *((int32_t *)&vals[43+(i*60)]);
        mainArray[i].chin = *((int32_t *)&vals[47+(i*60)]);
        mainArray[i].ground = *((int8_t *)&vals[51+(i*60)]);
        mainArray[i].veil = *(&vals[52+(i*60)]);
        mainArray[i].flowers = *((uint32_t *)&vals[53+(i*60)]);
        mainArray[i].adjustment = *((int8_t *)&vals[57+(i*60)]);
        mainArray[i].pets = *((int16_t *)&vals[58+(i*60)]);    
  }

  for(i = 0; i < structAmount; i ++){//prints
        printf("%c, %f, %s, %d, %c, %f, %d, %u, %f, %d, %d, %d, %d, %c, %u, %d, %d \n",
        mainArray[i].need,mainArray[i].ring,mainArray[i].fight,mainArray[i].uncle,mainArray[i].game,mainArray[i].war,mainArray[i].train,
        mainArray[i].beds,mainArray[i].crook,mainArray[i].feast,mainArray[i].rabbits,mainArray[i].chin,mainArray[i].ground,mainArray[i].veil,
        mainArray[i].flowers,mainArray[i].adjustment,mainArray[i].pets);//prints

  }
  free(vals);//frees the memory we allocated to vals

  stage2 *array = malloc(structAmount * structSize);

  for(i = 0; i < structAmount; i ++){
        array[i] = mainArray[i];  
  }
  printf("Before Sort\n\n");  
  for(i = 0; i < structAmount; i ++){
          printf("%c, %f, %s, %d, %c, %f, %d, %u, %f, %d, %d, %d, %d, %c, %u, %d, %d \n",
  array[i].need,array[i].ring,array[i].fight,array[i].uncle,array[i].game,array[i].war,array[i].train,
  array[i].beds,array[i].crook,array[i].feast,array[i].rabbits,array[i].chin,array[i].ground,array[i].veil,
  array[i].flowers,array[i].adjustment,array[i].pets);//prints 
  }
  qsort(array, structAmount,structSize,needS);


  printf("After Sort\n\n");  
  for(i = 0; i < structAmount; i ++){
          printf("%c, %f, %s, %d, %c, %f, %d, %u, %f, %d, %d, %d, %d, %c, %u, %d, %d \n",
  array[i].need,array[i].ring,array[i].fight,array[i].uncle,array[i].game,array[i].war,array[i].train,
  array[i].beds,array[i].crook,array[i].feast,array[i].rabbits,array[i].chin,array[i].ground,array[i].veil,
  array[i].flowers,array[i].adjustment,array[i].pets);//prints 
  }

  FILE *my_file = fopen(argv[2], "wb");
  for(i = 0; i < structAmount; i ++){
          fwrite(&mainArray[i].need, sizeof(char), 1, my_file);
          fwrite(&mainArray[i].ring, sizeof(double), 1, my_file);
          fwrite(&mainArray[i].fight, sizeof(char[8]), 1, my_file);
          fwrite(&mainArray[i].uncle, sizeof(int32_t), 1, my_file);
          fwrite(&mainArray[i].game, sizeof(char), 1, my_file);
          fwrite(&mainArray[i].war, sizeof(double), 1, my_file);
          fwrite(&mainArray[i].train, sizeof(int8_t), 1, my_file);
          fwrite(&mainArray[i].beds, sizeof(uint32_t), 1, my_file);
          fwrite(&mainArray[i].crook, sizeof(float), 1, my_file);
          fwrite(&mainArray[i].feast, sizeof(int32_t), 1, my_file);
          fwrite(&mainArray[i].rabbits, sizeof(int32_t), 1, my_file);
          fwrite(&mainArray[i].chin, sizeof(int32_t), 1, my_file);
          fwrite(&mainArray[i].ground, sizeof(int8_t), 1, my_file);
          fwrite(&mainArray[i].veil, sizeof(char), 1, my_file);
          fwrite(&mainArray[i].flowers, sizeof(uint32_t), 1, my_file);
          fwrite(&mainArray[i].adjustment, sizeof(int8_t), 1, my_file);
          fwrite(&mainArray[i].pets, sizeof(int16_t), 1, my_file);
  }

  fclose(my_file);

  return 0;//return statement
}
Run Code Online (Sandbox Code Playgroud)

我一直在处理代码的链接.我的主要问题是,从我收集的内容来看,当使用排序比较方法needS(第31行)进行排序的第一次执行时,它应该返回数组中前两个结构的第一个字段并打印它们(我知道这个不是一个有效的排序方法,但想确保变量符合我的预期.然而,这不是发生的事情; 该p1变量会打印出然而我所期望的p2变量不会.从这一点开始,每次使用它都会返回垃圾(我认为)值.

有什么我错过或做错了吗?

Jon*_*ler 5

你的问题在于这一行:

int structSize = 60;  //size of structs in bytes, sizeof() doesn't return correct val
Run Code Online (Sandbox Code Playgroud)

你错了; sizeof()确实返回正确的大小.无论你做什么都是假的.您需要回到序列化的基础知识.您需要正确地写入数据.您应该能够在单个读取操作中将所有数据读入阵列.如果输入中每条记录确实有60个字节,则会出现严重问题.请注意,内存中的结构布局在char need;double ring;元素之间的大多数系统(有些是3个)上浪费了7个字节.