首页 > 解决方案 > C: 使用 read() 将二进制数据读入结构数组,然后使用 qsort() 对数据进行排序

问题描述

*我必须先说我是 C 的一个全新的人。这是我的第一个程序之一。这将是一个冗长的帖子,对我来说如此空洞。我的任务如下:我必须将文件中的数据读取到结构数组中,然后我必须根据数据的键值对数据进行排序。到目前为止,这是我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "sort.h"
#include <errno.h>
#include <stdarg.h>

typedef struct record
{
    unsigned int key;
    char rec[96];
}record;


int comparator(const void *a, const void *c)
{
    const struct record *elem1 = a;
    const struct record *elem2 = c;
    if (elem1->key < elem2->key)
        return -1;
    else if(elem1->key > elem2->key)
        return 1;
    else
        return 0;
}

int main(int argc, char *argv[])
{
    printf("You entered %d arguments.\n", argc);
    if (argc != 5)
    {
        fprintf(stderr, "usage: ./fastsort -i [inputfile] -o [outputfile]\n");
        exit(1);
    }

    int option;
    int iflag;
    int oflag;
    char *outFile   = "/no/such/file";
    char *inFile   = "/no/such/file";
    while((option = getopt(argc, argv, "i:o:")) != -1){ //get option from the getopt() method
        switch(option){
            //For option i,o print that these are options
        case 'i':
            iflag = 1;
            break;
        case 'o': //here o is used for some file name
            outFile     = strdup(optarg);
            oflag = 1;
            break;
        case ':':
            printf("option needs a value\n");
            break;
        case '?': //used for some unknown options
            printf("unknown option: %c\n", optopt);
            break;
        }
    }

    printf("%s\n", argv[2]);
    inFile = argv[2];
    //OPEN FILE TO READ
    int sz;
    struct stat sfile;
    stat(inFile, &sfile);

    //STRUCT ARRAY HERE
    char* x = (char*) malloc(sfile.st_size + 1);
    record A[100];
    //

    printf("st_size = %ld\n", sfile.st_size);
   
    int fd = open(inFile, O_RDONLY|O_EXCL);
    printf("fd = %d\n", fd);
    //IF FILE ERROR, PRINT ERROR AND EXIT
    if (fd < 0)
    {
        perror("open");
        exit(1);
    }
    //READ CODE GOES HERE
    while (1)
    {
        int fr;
        fr = read(fd, &A, sizeof(record));
        if (fr == 0)
        {
            break;
        }
        printf("key: %u\n", A->key);
    }
    printf("KEYS PRINTED\n");
    printf("\n");
    printf("UNSORTED\n");
    //TEST PRINT ARRAY DATA
    for (int z = 0; z < 100; z++)
    {
        printf("%u\n", A[z].key);
    }
    printf("SORTING STARTED\n");
//----------------------------------------------
    qsort(A, 100, sizeof(record), comparator);
    int b;
    for (b = 0; b < 100; b++)
    {
        printf("%u\n",A[b].key);
    }

    //CLOSE FILE AND RETURN 0
    printf("\n");
    free(x);
    printf("Freed memory\n");
    close(fd);
    printf("Closed Open File\n");
    return(0);
}

我目前的问题如下:当我在while循环中读取数据并且printf("%u",A->key)键列表正确出现时,但是,当我使用z作为迭代器在底部打印结构数据的“数组”时,数据不会匹配任何想象力打印的键。因此,qsort() 对不正确的数据进行排序。我们必须排序的 key:record 列表的示例是:

key: 1804289383 rec:886 777 915 793 335 386 492 649 421 362 27 690 59 763 926 540 426 172 736 211 368 567 429 782 
key: 861021530 rec:862 123 67 135 929 802 22 58 69 167 393 456 11 42 229 373 421 919 784 537 198 324 315 370 
key: 1129566413 rec:526 91 980 956 873 862 170 996 281 305 925 84 327 336 505 846 729 313 857 124 895 582 545 814 
key: 1548233367 rec:434 364 43 750 87 808 276 178 788 584 403 651 754 399 932 60 676 368 739 12 226 586 94 539 
key: 1036140795 rec:570 434 378 467 601 97 902 317 492 652 756 301 280 286 441 865 689 444 619 440 729 31 117 97 
key: 2007905771 rec:481 675 709 927 567 856 497 353 586 965 306 683 219 624 528 871 732 829 503 19 270 368 708 715 
key: 1373226340 rec:149 796 723 618 245 846 451 921 555 379 488 764 228 841 350 193 500 34 764 124 914 987 856 743

每行是 100 字节,这就是为什么我的结构以它的格式布局的原因。密钥为 4 个字节,数据为 96 个字节。*排序时记录必须与键保持一致。输出文件当前不起作用,因为我出于测试目的打印了所有内容

标签: c

解决方案


推荐阅读