给定下面的二维数组:
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);
}
答案 0 :(得分: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;
}
答案 1 :(得分:3)
我相信你至少有一个问题:
strncpy(Result, ix + (Offset - LEN),LEN);
如果查看documentation for 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() documentaton,如果第一个参数被认为分别小于,等于或大于0,则可以看到返回值应为“小于,等于或大于零的整数”比第二个“。实现此目的的最简单方法是使用逻辑n1 - n2
而不是n1 < n2
。
我还认为你类型char **
的类型参数也很奇怪,但经过进一步的反思,我发现它们是正确的。来自qsort docs:“两个指向被比较对象的参数”。所以他们确实会指向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);
}