1

给定一个二维数组,如下所示:

char * Arr[4] = 
{
    {"124 -346  DATA...."},
    {"39479 -32 MOREDATA...."},
    {"12 -1 DATA2...."},
    {"100 -45 DATA4...."}
};

我正在尝试使用qsort()根据SECOND字段对该函数进行排序,这意味着将根据最低的第二个值(-1、-32、-45、-346)对字符串进行排序。如果每个值只有一个数字,我知道如何实现此功能,但程序中的数字可以任意长。这就是我所拥有的,但是程序崩溃了,如果有一种更有效的方法来对这些数据进行排序,我很想在这里(我知道我的方法效率不高)。

排序函数(qsort() 调用):

inline void GetStr(char *ix, char* Result)  //call to get second number in function
{
    char *spacing;              //iterator to traverse
    spacing = ix;               //iterator = pos of ix
    int LEN = 0;                //length and offset
    int Offset = 0;

    while(*spacing != ' ')      //while not at end of first num
    {
        Offset++;               //offset is more
        spacing++;
    }
    spacing++;                  //go one ahead of the space
    Offset++;

    while(*spacing != ' ')      //while not end of second number
    {
        spacing++;
        Offset++;
        LEN++;                  //length of number
    }
    strncpy(Result, ix + (Offset - LEN),LEN);
}

int sort(const void* a, const void* b)
{
    char *ia = *(char**)a;
    char *ib = *(char**)b;

    char * Str;
    char * Str2;
    GetStr(ia, Str);                                    //getting some strange errors....... program just crashes
    GetStr(ib, Str2);
    printf("Str: %s Str2: %s", Str, Str2);
    int n1 = atoi(Str);
    int n2 = atoi(Str2);
    return (n1 > n2);
}
4

2 回答 2

3

你可以从这样的东西开始,你需要在某个地方实际调用 sort 。还需要考虑文件很大时会发生什么:

#include <stdio.h>

int
Sort(const void *a, const void *b)
{
    int *aa = a, *bb = b;
    return (aa[1] < bb[1]); //i need to sort by field, not a simple comparison. HOW?
}

int main(int argc, char **argv) {
  FILE *f = fopen(argv[1]);
  if (f) {
    char buffer[1024];
    int *v;
    int data[1024][5];
    int cnt = 0;
    while (fgets(buffer, sizeof(buffer), f)) {
        v = data[cnt++];
        sscanf(buffer, "%d %d %d %d %d", v, v+1, v+2, v+3, v+4);
    }
    fclose(f);
  }
  return 0;
}
于 2012-11-28T22:16:22.873 回答
3

我相信你在这里至少有一个问题:

strncpy(Result, ix + (Offset - LEN),LEN);

如果您查看 的文档strncpy,您会发现如果您达到字符限制,它不会自动以空值终止复制的字符串。因此,您的Result字符串不是以空值结尾的。

尝试更改为:

strncpy(Result, ix + (Offset - LEN),LEN);
Result[LEN] = '\0';

当然,您仍然需要为 Result 字符串提供内存。当前,您正在将未初始化的指针传递给GetStr()

char * Str;
char * Str2;

由于这些是相当小的整数,您可以像这样使用静态分配的存储:

#define MAX_RESULT_LEN 64

/* ... */

char Str[MAX_RESULT_LEN]
char Str2[MAX_RESULT_LEN]

/* ... */

if (LEN > MAX_RESULT_LEN - 1) {
    LEN = MAX_RESULT_LEN - 1;
}

strncpy(Result, ix + (Offset - LEN),LEN);
Result[LEN] = '\0';

sort()最后,您的功能存在一些问题。如果您查看qsort() 文档,您可以看到返回值应该是“如果第一个参数分别被认为小于、等于或大于零,则返回值应该是“小于、等于或大于零的整数第二”。实现这一点的最简单方法是使用逻辑n1 - n2而不是n1 < n2.

我还认为您的类型论点也char **很奇怪,但经过进一步思考,我意识到它们是正确的。来自 qsort 文档:“指向被比较对象的两个参数”。所以实际上它们将是指向 C 字符串或char **.

所以这是最终版本:

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

#define MAX_RESULT_LEN 64

void GetStr(char *ix, char* Result)  //call to get second number in function
{
    char *spacing;              //iterator to traverse
    spacing = ix;               //iterator = pos of ix
    int LEN = 0;                //length and offset
    int Offset = 0;

    while(*spacing != ' ')      //while not at end of first num
    {
        Offset++;               //offset is more
        spacing++;
    }
    spacing++;                  //go one ahead of the space
    Offset++;

    while(*spacing != ' ')      //while not end of second number
    {
        spacing++;
        Offset++;
        LEN++;                  //length of number
    }

    if (LEN > MAX_RESULT_LEN - 1) {
        LEN = MAX_RESULT_LEN - 1;
    }

    strncpy(Result, ix + (Offset - LEN),LEN);
    Result[LEN] = '\0';
}

int sort(const void* a, const void* b)
{
    char *ia = *(char **)a;
    char *ib = *(char **)b;

    char Str[MAX_RESULT_LEN];
    char Str2[MAX_RESULT_LEN];

    GetStr(ia, Str);
    GetStr(ib, Str2);

    printf("Str: %s Str2: %s", Str, Str2);
    int n1 = atoi(Str);
    int n2 = atoi(Str2);
    return (n1 - n2);
}

int main(void) {
    char * Arr[4] = 
    {
        {"124 -346  DATA...."},
        {"39479 -32 MOREDATA...."},
        {"12 -1 DATA2...."},
        {"100 -45 DATA4...."}
    };

    qsort(Arr, 4, sizeof(char *), sort);
}
于 2012-11-30T22:19:34.830 回答