Как исправить «discard const» в функции c qsort (массив является массивом указателей), может быть связано с пониманием указателей - PullRequest
0 голосов
/ 08 февраля 2019

Я учу C на данный момент.в настоящее время изучает указатель c (массивы указателей).То, что пытается сделать приведенный ниже код (в двух словах прототип C), - это читать текст из stdin, строка за строкой.каждый элемент массива является указателем на одну строку текста, а затем сортирует текст, просто сортируя указатели.Когда я пытаюсь скомпилировать мой код, компилятор (gcc) выдает мне предупреждение "discard const", я пытался добавить приведение (const char **) в функцию str_compare, но все еще не решаю мою проблему

Я думаю, это может быть связано с моим пониманием указателей c.Может ли кто-то помочь указать, где и я сделал неправильно, в чем проблема в моем коде, пожалуйста?

Я включил много флагов предупреждений и воспринимаю все предупреждения как ошибки в gcc.Я могу понять указатели, и я раньше использовал qsort, все получилось хорошо.Но это первый раз, когда я кодирую указатель на указатели.поэтому я думаю, что у меня может быть некоторое недопонимание здесь.

// Read text line by line then sort them, use point array

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

char *getLine(void);
int str_compare(const void *, const void *);

#define NLINES_MAX 1000
char *linePtr[NLINES_MAX];

int main()
{
    // Read lines;
    int long unsigned n = 0;
    for ( ; n < NLINES_MAX && (linePtr[n] = getLine()) != NULL; ++n)
        ;

    if ( !feof(stdin))
    {
        if (n == NLINES_MAX)
            fputs("sorttex: too many lines.\n", stderr);
        else
        {
            fputs ("sorttext: error reading from stdin.\n", stderr);
        }
    }
    else
    {
        qsort(linePtr, n, sizeof(char *), str_compare);
        for ( char **p = linePtr; p < linePtr +n; ++p)
            puts(*p);
    }
    return 0;
}

int str_compare(const void *p1, const void *p2)
{
    return strcmp(*(const char **)p1, *(const char **)p2);
}

#define LEN_MAX 512

char *getLine()
{
    char buffer[LEN_MAX], *lineP = NULL;
    if (fgets (buffer, LEN_MAX, stdin) != NULL)
    {
        size_t len = strlen(buffer);
        if (buffer[len-1] =='\n')
            buffer[len-1] = '\0';
        else
        {
            ++len;
        }
        if ((lineP = malloc(len)) != NULL)
            strcpy( lineP, buffer);
    }
    return lineP;
}

Флаги gcc:

-std=c11 -pedantic-errors -pipe -O2 -Wall -Werror -Wextra -Wfloat-equal \
-Wshadow -Wpointer-arith -Wcast-align -Wstrict-overflow=5 -Wwrite-strings \
-Waggregate-return -Wcast-qual -Wswitch-default -Wswitch-enum -Wconversion \
-Wunreachable-code -Winit-self -march=native

Я ожидаю избавиться от "сбросить const"предупреждающее сообщение

Ответы [ 2 ]

0 голосов
/ 08 февраля 2019

Строка может быть:

return strcmp(*(char *const *)p1, *(char *const *)p2);

Сортируемые элементы указатели на char * (не указатели на const char *, как сказал бы ваш код).А внутренний const должен гарантировать, что функция сравнения не изменяет сравниваемые объекты (которые являются char * объектами, следовательно, char * const).

Конечно, расширяя его дополнительными переменнымикак показывает jxh, тоже неплохая идея.

0 голосов
/ 08 февраля 2019

Аргумент, переданный функции str_compare, является адресом элемента массива.Элемент массива имеет тип char *, и вызывающая сторона str_compare будет обрабатывать его как const, а затем передавать адрес. Таким образом, вы фактически получите char * const *.

Итак,const void * на самом деле

указатель на постоянный указатель на символ

и НЕ

указатель на указатель на постоянный символ

, как вы кодировали.

int str_compare(const void *p1, const void *p2)
{
    char * const *pp1 = p1;
    char * const *pp2 = p2;
    return strcmp(*pp1, *pp2);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...