0

次のように定義された関数があります(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

4 に答える 4

1

コードがポインターへのポインターを返す理由はよくわかりませんが、それにより、目的の操作が少し難しくなります。ポインター自体だけでなく、ポインターのアドレスを返す必要があるため、その新しいポインターをどこかに割り当てる必要があります (そして、誰がそれを解放しますか?)。メモリ リークが気にならない場合は、問題を無視してポインタを割り当て、そのアドレスを返すことができます。File_Tagまたは、の最初の文字を含む短い文字列を保持するの新しいメンバーを作成できますartist

これにはglib 文字列関数が役立ちます。リスト ショーをざっと見てみる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);

コードがアーティスト名の最初の文字を含む新しい文字列を返す場合、正確に何をしたいのかわかりません。上記のコードは、新しく割り当てられた文字列が指すものを変更しますが、実際のアーティスト名には影響しません。

于 2009-11-26T18:54:31.797 に答える
1

目標が最初の文字のみで構成される文字列へのポインターを返すことであり、スレッドセーフを気にしない場合は、次のように動作するはずです。

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

ただし、単に「char」へのポインターではなく、「char」へのポインターへのポインターを返すのは奇妙だと思います。

于 2009-11-26T19:01:57.850 に答える
0

インターネットを精査しないでください。自分でコーディングしてください。これを追加:

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

&FileTag->artistそれは が type であると仮定していgchar **ます。

于 2009-11-26T18:51:36.283 に答える
0

可能であれば、アーティスト文字列全体を取得してから、関数を呼び出した場所から最初の文字にアクセスするだけです。

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

それができない場合は、キャラクターに新しいメモリを割り当てることもできますが、ポインターをポインターに返す必要があるため、これはややこしいことです。そのため、そのポインタにもメモリを割り当てる必要があります。多分あなたはそれを変えることができます...

于 2009-11-26T18:59:40.510 に答える