Указатели на структуры в C

При попытке скомпилировать следующий код я получаю предупреждение о том, что строка 18 создает целое число из указателя без приведения и что 19 и 20 являются несовместимыми типами при назначении. Я новичок в структурах в C и не могу понять, что не так.

#include <stdio.h>

struct song
{       char title[70];
};

struct playlist
{       struct song songs[100];
};

void title_sort(struct playlist * list,int len)
{       int swapped = 1,i;
        char hold;
        while (swapped)
        {       swapped = 0;
                for (i = 0;i < len - 1; i++)
                {       if (list->songs[i].title > list->songs[i+1].title)
                        {       hold = list->songs[i].title;
                                list->songs[i].title = list->songs[i+1].title;
                                list->songs[i+1].title = hold;
                                swapped = 1;
                        }
                }
        }
}

int main()
{       struct playlist playlist;
        int i;
        for (i = 0;i < 5;i++)
        {       fgets(playlist.songs[i].title,70,stdin);
        }
        title_sort(&playlist,5);
        printf("\n");
        for (i = 0;i < 5;i++)
        {       printf("%s",playlist.songs[i].title);
        }
        return 0;
}

person bandwevil    schedule 08.11.2009    source источник


Ответы (5)


Вы не можете сравнивать строки в C с >. Вам нужно использовать strcmp. Также hold это char, но заголовок char [70]. Вы можете копировать указатели на строки, но массивы нельзя скопировать только с помощью =.

Вы можете использовать strcpy следующим образом:

void title_sort(struct playlist * list,int len)
{       int swapped = 1,i;
        char hold[70];
        while (swapped)
        {       swapped = 0;
                for (i = 0;i < len - 1; i++)
                    {       if (strcmp (list->songs[i].title, list->songs[i+1].title) > 0)
                            {       strcpy (hold, list->songs[i].title);
                                strcpy (list->songs[i].title, list->songs[i+1].title);
                                strcpy (list->songs[i+1].title,hold);
                                swapped = 1;
                        }
                }
        }
}

Но обратите внимание, что в C вам нужно проверять такие вещи, как длина строк, поэтому приведенный выше код опасен. Вам нужно либо использовать strncpy, либо использовать strlen для проверки длины строк.

person Community    schedule 08.11.2009

Вы не можете использовать такие строки в C. Строки — это, по сути, простой массив символов в C без специализированных операторов, таких как =, ‹ и т. д. Вам нужно использовать строковые функции, такие как strcmp и strcpy, чтобы выполнять манипуляции со строками.

person Naveen    schedule 08.11.2009

Чтобы быть более конкретным: следующее неверно

if (list->songs[i].title > list->songs[i+1].title)

Сделайте это следующим образом:

if( strcmp (list->songs[i].title , list->songs[i+1].title) > 0 )
person Pale Blue Dot    schedule 08.11.2009
comment
Вам не хватает > 0) в конце фрагмента. - person Adam Rosenfield; 08.11.2009

  • char hold должно быть чем-то другим, возможно, char *hold, возможно, массивом.
  • C не имеет назначения массива, хотя у него есть назначение структуры, вам нужно будет переработать это
person DigitalRoss    schedule 08.11.2009

Ваша первая проблема в строке 18 вызвана двумя проблемами. Во-первых, переменная hold может содержать только одно значение char, а вы пытаетесь присвоить ей массив из 70 char.

Сначала вам нужно сделать hold правильного типа:

char hold[70];

Теперь есть еще одна проблема — массивы нельзя просто присвоить с помощью оператора =. Вы должны использовать функцию для явного копирования данных из одного массива в другой. Вместо вашей текущей строки 18 вы можете использовать:

memcpy(hold, list->songs[i].title, 70);

Затем вам нужно сделать то же самое для строк 19 и 20:

memcpy(list->songs[i].title, list->songs[i+1].title, 70);
memcpy(list->songs[i+1].title, hold, 70);

В качестве альтернативы вы можете написать цикл и поменять местами два заголовка по одному символу за раз.

Точно так же вы не можете сравнивать две строки с помощью простого оператора < — для этого вам тоже нужно использовать функцию (например, strcmp).

person caf    schedule 08.11.2009