Question

I have a function defined as the following (in 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;
    }
}

I am trying to add a new condition to the switch statement, such as

case 'f':

In which it would return the first character of &FileTag->artist.

I have scoured all of the internet looking for a solution, but have come up empty handed. Anyone have any ideas?

Update: If it helps, this function is part of the application EasyTag. From what I have seen looking through the code, this is where the new file name for easytag's file sorting feature is determined. I am trying to add a new variable to allow the application to sort music into directories like so: <First letter of artist name>/<Artist>/<Album>/<Tracks>

There is always the chance that I may be looking at the wrong function, but to the best of my knowledge I am.

Another Update: I got this function working as I wanted (pointers are funny little things), but it does not, as pointed out below, do what I had expected it to. Thanks for all the help and patience!

Was it helpful?

Solution

I'm not quite sure why your code returns a pointer to a pointer, but that makes your desired operation slightly more difficult. Since you need to return the address of a pointer, and not just a pointer itself, you have to allocate that new pointer somewhere (and then who will free it?). If you don't mind the memory leak you can ignore the problem and just allocate a pointer and return its address. Or, you can create a new member of File_Tag that holds a short string that contains the first character of artist.

The glib string functions will be helpful for this, a quick look through the list shows g_strdup_printf() might be useful:

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

Then allocate somewhere to store first and return the address of that.

Update: Using http://codesearch.google.com I seem to have found where this function you're changing is used, and it looks like the return value is used to change the field that is returned.

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

I'm not sure what exactly you want to do if your code returns a new string that contains the first character of the artist name. The above code would change what your newly allocated string points to, which would have no effect on the actual artist name.

OTHER TIPS

If the goal is to return a pointer to a string that comprises only the first letter and you don't care about thread-safety, then the following should work

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

I find it odd, however, that you're returning a pointer to a pointer to a "char" rather that simply a pointer to a "char".

Don't scour the internet. Code it yourself. Add this:

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

That's assuming &FileTag->artist is of type gchar **.

If possible, I would just get the whole artist string and then simply access the first letter from wherever you call the function:

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

If that is not an option, you could allocate new memory for your character, but that is rather tricky because you want to return a pointer to a pointer. So you would have to allocate also memory for that pointer. maybe you could change that ...

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top