Проблема с функцией C, возвращающей gchar ** - PullRequest
0 голосов
/ 26 ноября 2009

У меня есть функция, определенная следующим образом (в C):

gchar **Scan_Return_File_Tag_Field_From_Mask_Code (File_Tag *FileTag, gchar code)
{
    switch (code)
    {
        case 't':    /* Title */
            return &FileTag->title;
        case 'a':    /* Artist */
            return &FileTag->artist;
        case 'b':    /* Album */
            return &FileTag->album;
        case 'd':    /* Disc Number */
            return &FileTag->disc_number;
        case 'y':    /* Year */
            return &FileTag->year;
        case 'n':    /* Track */
            return &FileTag->track;
        case 'l':    /* Track Total */
            return &FileTag->track_total;
        case 'g':    /* Genre */
            return &FileTag->genre;
        case 'c':    /* Comment */
            return &FileTag->comment;
        case 'p':    /* Composer */
            return &FileTag->composer;
        case 'o':    /* Orig. Artist */
            return &FileTag->orig_artist;
        case 'r':    /* Copyright */
            return &FileTag->copyright;
        case 'u':    /* URL */
            return &FileTag->url;
        case 'e':    /* Encoded by */
            return &FileTag->encoded_by;
        case 'i':    /* Ignored */
            return NULL;
        default:
            Log_Print(LOG_ERROR,"Scanner: Invalid code '%%%c' found!",code);
            return NULL;
    }
}

Я пытаюсь добавить новое условие в оператор switch, например

case 'f':

В котором будет возвращен первый символ & FileTag-> artist.

Я искал весь интернет в поисках решения, но пришел с пустыми руками. У кого-нибудь есть идеи?

Обновление: Если это помогает, эта функция является частью приложения EasyTag. Из того, что я видел, просматривая код, именно здесь определяется новое имя файла для функции сортировки файлов easytag. Я пытаюсь добавить новую переменную, чтобы приложение могло сортировать музыку по каталогам следующим образом: <First letter of artist name>/<Artist>/<Album>/<Tracks>

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

Другое обновление: Я получил эту функцию, работающую так, как я хотел (указатели - забавные мелочи), но, как указано ниже, она не выполняет то, что ожидал Спасибо за помощь и терпение!

Ответы [ 4 ]

1 голос
/ 26 ноября 2009

Если цель состоит в том, чтобы вернуть указатель на строку, содержащую только первую букву, и вас не заботит безопасность потоков, тогда должно работать следующее

static char buf[2];
static char *pbuf = buf;
...
case 'f':
    buf[0] = FileTag->artist[0];
    return &pbuf;

Однако я нахожу странным, что вы возвращаете указатель на указатель на "char", а не просто указатель на "char".

1 голос
/ 26 ноября 2009

Я не совсем уверен, почему ваш код возвращает указатель на указатель, но это немного усложняет желаемую операцию. Поскольку вам нужно возвращать адрес указателя, а не только сам указатель, вы должны разместить этот новый указатель где-нибудь (и тогда кто его освободит?). Если вы не возражаете против утечки памяти, вы можете проигнорировать проблему и просто выделить указатель и вернуть его адрес. Или вы можете создать новый элемент File_Tag с короткой строкой, содержащей первый символ artist.

Для этого будут полезны функции glib string , быстрый просмотр списка показывает, g_strdup_printf() может быть полезно:

gchar *first = g_strdup_printf("%c", FileTag->artist[0]);

Затем выделите место для хранения first и верните адрес этого.

Обновление: Использование http://codesearch.google.com Кажется, я нашел, где используется изменяемая функция , и похоже, что возвращаемое значение используется для изменить поле, которое возвращается.

    // Get the target entry for this code
    dest = Scan_Return_File_Tag_Field_From_Mask_Code(FileTag,mask_item->code);

    // We display the text affected to the code
    if ( dest && ( OVERWRITE_TAG_FIELD || *dest==NULL || strlen(*dest)==0 ) )
        ET_Set_Field_File_Tag_Item(dest,mask_item->string);

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

0 голосов
/ 26 ноября 2009

Если возможно, я бы просто получил всю строку исполнителя, а затем просто получил бы доступ к первой букве, откуда бы вы ни вызывали функцию:

gchar **artist = Scan_Return_File_Tag_Field_From_Mask_Code (File_Tag *FileTag, 'f')
printf("%c", *artist[0]);

Если это не вариант, вы можете выделить новую память для вашего персонажа, но это довольно сложно, потому что вы хотите вернуть указатель на указатель. Таким образом, вы должны были бы также выделить память для этого указателя. может быть, вы могли бы изменить это ...

0 голосов
/ 26 ноября 2009

Не рыскать по интернету. Кодируй это сам. Добавьте это:

        case 'f':    /* Artist */
            return &FileTag->artist;

Предполагается, что &FileTag->artist имеет тип gchar **.

...