C函数返回gchar的问题**

时间:2009-11-26 18:42:05

标签: c pointers switch-statement glibc

我有一个定义如下的函数(在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->艺术家的第一个角色。

我已经搜索了所有互联网寻找解决方案,但空手而归。有人有什么想法吗?

更新 如果有帮助,此功能是EasyTag应用程序的一部分。从我看到的代码看,这是easytag的文件排序功能的新文件名确定。我正在尝试添加一个新变量,以允许应用程序将音乐分类到如下目录:<First letter of artist name>/<Artist>/<Album>/<Tracks>

我总是有机会看到错误的功能,但据我所知,我是。

另一个更新: 我按照自己的意愿运行了这个函数(指针是有趣的小东西),但它没有像下面所指出的那样按照我的预期行事。感谢所有的帮助和耐心!

4 个答案:

答案 0 :(得分:1)

我不太清楚为什么你的代码返回一个指向指针的指针,但这会使你想要的操作稍微困难一些。既然你需要返回一个指针的地址,而不仅仅是一个指针本身,你必须在某处分配那个新指针(然后谁将释放它?)。如果你不介意内存泄漏,你可以忽略这个问题,只需分配一个指针并返回它的地址。或者,您可以创建File_Tag的新成员,该成员包含一个包含artist的第一个字符的短字符串。

glib string functions对此有所帮助,快速查看列表显示g_strdup_printf()可能有用:

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

然后分配一个地方来存储first并返回该地址。

更新:使用http://codesearch.google.com我似乎有found where this function you're changing is used,看起来返回值用于更改字段返回。

    // 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);

如果你的代码返回一个包含艺术家名字第一个字符的新字符串,我不确定你想要做什么。上面的代码会改变你新分配的字符串指向的内容,这对实际的艺术家名称没有影响。

答案 1 :(得分:1)

如果目标是返回指向仅包含第一个字母的字符串的指针而您不关心线程安全性,那么以下内容应该可以正常工作

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

然而,我觉得很奇怪,你正在返回一个指向“char”指针的指针而不是指向“char”的指针。

答案 2 :(得分:0)

不要搜索互联网。自己编码。加上这个:

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

假设&FileTag->artist的类型为gchar **

答案 3 :(得分:0)

如果可能的话,我会得到整个艺术家的字符串,然后只需从你调用该函数的地方访问第一个字母:

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

如果这不是一个选项,你可以为你的角色分配新的内存,但这是相当棘手的,因为你想返回一个指针指针。所以你必须为该指针分配内存。也许你可以改变它......