【问题标题】:Issue with C function returning a gchar**C 函数返回 gchar 的问题**
【发布时间】:2009-11-26 18:42:05
【问题描述】:

我有一个函数定义如下(在 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>

我总是有可能正在查看错误的函数,但据我所知,我是。

另一个更新: 我让这个函数按我的意愿工作(指针是有趣的小东西),但它并没有像下面指出的那样做我所期望的。感谢所有的帮助和耐心!

【问题讨论】:

  • 你能解释一下 case 'f' 和 case 'a' 有什么不同吗?
  • 大小写“a”返回整个艺术家姓名,新的“f”只返回第一个字母。 IE:Pink Floyd 的审判“a”将返回“Pink Floyd”“f”将返回“P”
  • 该函数返回一个gchar **。如果'Pink Floyd'和'P'都是gchar **类型,你应该没问题。
  • 场景是我有一个字符串“/home/user/music/%f/”。我有一个函数贯穿这个字符串,并以 \%[a-zA-Z] 的形式挑选出任何东西,并将字母与文件标记对象一起传递给这个函数。然后,此函数扩展该“标签”(% 字母)并将其返回以用于对文件进行排序。

标签: c pointers switch-statement glibc


【解决方案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);

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

【讨论】:

  • 我一直在考虑这些思路...但是当我尝试这样做时,我得到“格式 '%c' 需要类型 'int',但参数 2 的类型为 'gchar *'”...
  • 您确定您使用的是artist[0] 而不仅仅是artist
  • 逐字逐句(复制粘贴)我有 "gchar *first = g_strdup_printf("%c", &FileTag->artist[0]);"
  • 这不是我的建议。我确实更正了我的示例以包含FileTag->,但您以某种方式在其中添加了一个额外的&
  • 我明白了.. 不知道为什么我添加了那个。唉,这行得通,但它现在抱怨“从不兼容的指针类型返回”......这是我反复遇到的问题
【解决方案2】:

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

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

然而,我觉得奇怪的是,您返回的是指向“char”指针的指针,而不是简单的“char”指针。

【讨论】:

    【解决方案3】:

    不要上网。自己编码。添加这个:

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

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

    【讨论】:

      【解决方案4】:

      如果可能的话,我会获取整个艺术家字符串,然后简单地从您调用该函数的任何位置访问第一个字母:

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

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

      【讨论】:

      • 这不是一个选项。这是来自其他来源的代码,我正在对其进行调整以满足我的需求。调用算法过于复杂,无法重写
      猜你喜欢
      • 2020-03-15
      • 1970-01-01
      • 2020-06-21
      • 2013-11-25
      • 1970-01-01
      • 1970-01-01
      • 2021-12-13
      • 2014-07-25
      • 2013-03-02
      相关资源
      最近更新 更多