C 按特定字段对二维字符串数组进行排序
给定一个二维数组,如下所示:C 按特定字段对二维字符串数组进行排序,c,arrays,sorting,multidimensional-array,qsort,C,Arrays,Sorting,Multidimensional Array,Qsort,给定一个二维数组,如下所示: char * Arr[4] = { {"124 -346 DATA...."}, {"39479 -32 MOREDATA...."}, {"12 -1 DATA2...."}, {"100 -45 DATA4...."} }; 我试图根据SECOND字段对该函数进行排序,这意味着字符串将根据最低秒值(-1,-32,-45,-346)排序。如果每个值只有一个数字,我知道如何实现这个函数,但是程序中的数字可以任意长。这是我所拥有的
char * Arr[4] =
{
{"124 -346 DATA...."},
{"39479 -32 MOREDATA...."},
{"12 -1 DATA2...."},
{"100 -45 DATA4...."}
};
我试图根据SECOND字段对该函数进行排序,这意味着字符串将根据最低秒值(-1,-32,-45,-346)排序。如果每个值只有一个数字,我知道如何实现这个函数,但是程序中的数字可以任意长。这是我所拥有的,但是程序崩溃了,如果有一种更有效的方法来对这些数据进行排序,我很乐意在这里找到它(我知道我的方法不可能非常有效)
排序函数(qsort()调用该函数):
你可以这样开始,你需要在某处调用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;
}
#包括
int
排序(常数无效*a,常数无效*b)
{
int*aa=a,*bb=b;
return(aa[1]
您可以从这样的内容开始,实际上需要在某个地方调用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;
}
#包括
int
排序(常数无效*a,常数无效*b)
{
int*aa=a,*bb=b;
return(aa[1]
我相信您至少有一个问题:
strncpy(Result, ix + (Offset - LEN),LEN);
如果查看,您将看到,如果达到字符限制,它不会自动为null并终止复制的字符串。因此,结果
字符串不是以null结尾的
尝试更改为:
strncpy(Result, ix + (Offset - LEN),LEN);
Result[LEN] = '\0';
当然,您仍然需要为结果字符串提供内存。当前,您正在将未初始化的指针传递到GetStr()
:
由于这些是相当小的整数,您可以像这样使用静态分配的存储:
#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()
函数存在一些问题。如果查看,可以看到返回值应为“如果第一个参数分别小于、等于或大于第二个参数,则返回值应为小于、等于或大于零的整数”。实现这一点的最简单方法是使用逻辑n1-n2
而不是n1
我还以为您正在排序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);
}
#包括
#包括
#包括
#定义最大结果长度64
void GetStr(char*ix,char*Result)//调用以获取函数中的第二个数字
{
char*spating;//要遍历的迭代器
间距=ix;//迭代器=ix的位置
int LEN=0;//长度和偏移量
整数偏移=0;
while(*间距!='')//不在第一个数值的末尾
{
偏移量+++;//偏移量更大
间距++;
}
空格+++;//在空格前面加一个空格
Offset++;
while(*间距!='')//而不是第二个数字的结尾
{
间距++;
Offset++;
LEN++;//数字的长度
}
如果(长度>最大结果长度-1){
LEN=最大结果LEN-1;
}
strncpy(结果,ix+(偏移量-LEN),LEN);
结果[LEN]='\0';
}
整数排序(常量无效*a,常量无效*b)
{
字符*ia=*(字符**)a;
char*ib=*(char**)b;
char Str[MAX_RESULT_LEN];
字符Str2[MAX_RESULT_LEN];
GetStr(ia,Str);
GetStr(ib,Str2);
printf(“Str:%s Str2:%s”,Str,Str2);
int n1=atoi(Str);
int n2=原子(Str2);
返回(n1-n2);
}
内部主(空){
字符*Arr[4]=
{
{“124-346数据…”,
{“39479-32更多数据…”,
{“12-1数据2…”,
{“100-45数据4…”
};
qsort(Arr,4,sizeof(char*),sort);
}
我相信您至少有一个问题:
strncpy(Result, ix + (Offset - LEN),LEN);
如果查看,您将看到,如果达到字符限制,它不会自动为null并终止复制的字符串。因此,结果
字符串不是以null结尾的
尝试更改为:
strncpy(Result, ix + (Offset - LEN),LEN);
Result[LEN] = '\0';
当然,您仍然需要为结果字符串提供内存。当前,您正在将未初始化的指针传递到GetStr()
:
由于这些是相当小的整数,您可以像这样使用静态分配的存储:
#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()
函数存在一些问题。如果查看,可以看到返回值应为“如果第一个参数分别小于、等于或大于第二个参数,则返回值应为小于、等于或大于零的整数”。实现这一点的最简单方法是使用逻辑n1-n2
而不是n1
我还以为您正在排序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);
}
#包括
#包括
#包括
#定义最大结果长度64
void GetStr(char*ix,char