LINUX.ORG.RU

qsort для строк


0

0

#define LINES 65536 // Максимальное количество строк для сортировки
#define MAXCHARSINLINE 1024 // Максимальное количество символов в строке
#define NUMBER_OF_STRINGS (sizeof(strings)/sizeof(strings[0]))

char *strings[LINES];

static int cmp(const void *left, const void *right)
{
char *l = (char *) left;
char *r = (char *) right;
l += posofword;
r += posofword;
return strncmp(r, l, wordlen);
}

main
...
qsort(strings, NUMBER_OF_STRINGS, sizeof(char *), cmp);

Сортировка проходит не правильно - где может быть ошибка?

★★★★★

static int cmp(const void *left, const void *right)
{
   char *l = *(char **) left;
   char *r = *(char **) right;
   l += posofword;
   r += posofword;
   return strncmp(r, l, wordlen);
} 

kosmonavt
()

Да, забыл:
int posofword, wordlen; // Позиция слов в строке и их длина

UVV ★★★★★
() автор топика
Ответ на: комментарий от kosmonavt

> char *l = *(char **) left;
> char *r = *(char **) right;
segmentation fault

UVV ★★★★★
() автор топика
Ответ на: комментарий от kosmonavt

Сравнивать по определённой части строки!

UVV ★★★★★
() автор топика

>Сортировка проходит не правильно - где может быть ошибка?

Массив заполняется правильно? strcmp правильно работает для твоих строк (напр. не используются ли там русские буквы)?

Ты бы для отладки печатал, что передается в cmp ...

anonymous
()
Ответ на: комментарий от kosmonavt

Breakpoint 1, cmp (left=0x804a2a0, right=0x804a2a4) at sortarraybydate.c:43
43              char *l = (char *) left;
(gdb) s
44              char *r = (char *) right;
(gdb) s
47              l += posofword;
(gdb) s
48              r += posofword;
(gdb) s
49
(gdb) p posofword
$1 = 51
(gdb) p word
wordexp   wordfree  wordlen
(gdb) p wordlen
$2 = 16

UVV ★★★★★
() автор топика
Ответ на: комментарий от UVV

>43 char *l = (char *) left;

Насколько я понимаю, в cmp передаются указатели на элементы сортируемого массива. Элементами сортируемого массива являются указатели на char. Так что правильно вроде бы char *l = *(char**)left; Если оно у тебя падает, то хочется узнать, как ты формируешь массив.

anonymous
()
Ответ на: комментарий от anonymous

size_t size = 0;
ssize_t ret;

for (i = 0, strings[i] = NULL; i < LINES && (ret = getline(&strings[i], &size, finput)) != EOF ; i++, numberoflines++) {
                                strings[i+1] = NULL;
}

UVV ★★★★★
() автор топика
Ответ на: комментарий от UVV

> numberofstrings
в смысле numberoflines ;-))

UVV ★★★★★
() автор топика
Ответ на: комментарий от kosmonavt

Всем спасибо!
Работает вот так:

static int cmp(const void *left, const void *right)
{
        char *l = *(char **) left;
        char *r = *(char **) right;
        l += posofword;
        r += posofword;
        return strncmp(l, r, wordlen);
}

qsort(strings, numberoflines + 1, sizeof(char *), cmp);

И если можно, поподробней объясните конструкцию char *l = *(char **) left;
Это мы приводим left к типу char ** и берём на него указатель, так?

UVV ★★★★★
() автор топика
Ответ на: комментарий от UVV

>И если можно, поподробней объясните конструкцию char *l = *(char **) left;

В cmp передаются указатели элементов. у тебя был массив указателей на char, значит в cmp должны передаваться указатели на указатели на char.

kosmonavt
()
Ответ на: комментарий от kosmonavt

Спасибо, пойду знакомиться с типом void!

UVV ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.