I'm new to C programming and I am trying to write a simple ID3 tag editor for mp3s. An id3v1 tag is the last 128 bytes of the file, with 30 characters for the artist, 30, for the title, etc...

So far I have written this program which saves each tag to a separate string displays the tags:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char title[30];
    char artist[30];
    char album[30];
    char year[4];
    char comment[30];
    FILE *fp;

         //OPEN FILE
         fp = fopen("test.mp3", "rb");
         
         //GO TO TITLE BLOCK & READ
         fseek(fp, -125, SEEK_END);
         fread(title, 30, 1, fp);
              
         printf("Title: "); puts(title);
         
         
         //GO TO ARTIST BLOCK & READ
         fseek(fp, 0, SEEK_CUR);
         fread(artist, 30, 1, fp);
              
         printf("Artist: "); puts(artist);
         
         
         //GO TO ALBUM BLOCK & READ
         fseek(fp, 0, SEEK_CUR);
         fread(album, 30, 1, fp);
              
         printf("Album: "); puts(album);
         
         
         //GO TO YEAR BLOCK & READ
         fseek(fp, 0, SEEK_CUR);
         fread(year, 4, 1, fp);
              
         year[4] = '\0' ;
         printf("Year: "); puts(year);
         
         
         //GO TO COMMENT BLOCK & READ
         fseek(fp, 0, SEEK_CUR);
         fread(comment, 30, 1, fp);
              
         printf("Comment: "); puts(comment);
         





    printf("\n\n\n");
    system("pause");
    return 0;

//END MAIN
}

From what i've read so far I think I can use the one file pointer I have to read from and write to the file if I use the "r+b" argument in my fopen function.

It shouldn't be hard for me to add something to the program that would let the user rename each string, but I don't know how i would go about writing the changed strings back to the file. Any help would be appreciated.

I am also having an issue with the year string. It is 4 bytes long and when i try to print my year string it prints the 4 character long year string, plus the album string next to it (which is why I added the " year[4] = '\0' ; " code. I'm guessing the fread function doesn't add the \0 character to the end of the string?


Here is the mp3 file i'm working with:

http://dl.dropbox.com/u/3679894/test.mp3

Edited 5 Years Ago by ChEeZeBaLL: n/a

Hi there,

This isn't something that I've done my self before, but to write the data back to the file I think that you need to open the file with r+b like you said and then use fseek() to get to the part that you want to start writing and then use fwrite() to write the new data to the file.

I'm not sure what you mean when you say that it prints the album string next to the year, but I wouldn't do anything to year[4] , since year is only 4 elements long and year[4] is the element after the last element of year . I would make year 5 elements long if and get the first 4 from the file and add the final \0 manually.

I find that http://www.cplusplus.com/reference/clibrary is a really good reference for these functions (you just click on the header file on the left and all the functions are shown to you.

Hope that helps a little.

thanks for the tip, i'll start tinkering with the fwrite() function tonight.

Here is a screenshot of the "year" string issue I was referring to:

http://dl.dropbox.com/u/3679894/SN1.JPG


As you can see, it is printing the year, along with the album name on the same line.

Oh dude :icon_frown: There's no year[4] , you're corrupting memory.
Also fseek(fp, 0, SEEK_CUR); is meaningless. printf("Title: "); puts(title); is stupid, when there's printf("Title: %s\n", title); but apparently it failed cause you don't know about C-strings. You don't know about arrays. You don't know Stream I/O, how file pointers behave after read/write. You don't know C.
You cannot develop programs by second guessing what the statements you type perform.
Honestly, why do you guys insist on using C?

Comments
Lighten up. Some people aren't geniuses like you that know this stuff instinctually. They actually need to LEARN and make mistakes

Oh dude :icon_frown: There's no year[4] , you're corrupting memory.
Also fseek(fp, 0, SEEK_CUR); is meaningless. printf("Title: "); puts(title); is stupid, when there's printf("Title: %s\n", title); but apparently it failed cause you don't know about C-strings. You don't know about arrays. You don't know Stream I/O, how file pointers behave after read/write. You don't know C.
You cannot develop programs by second guessing what the statements you type perform.
Honestly, why do you guys insist on using C?

Er, this is all a bit unfair, and not particularly constructive! If you don't want to help, then don't. But this is a forum, where people who don't know the answers to question can ask for help.

Comments
Agreed

Oh dude :icon_frown: There's no year[4] , you're corrupting memory.
Also fseek(fp, 0, SEEK_CUR); is meaningless. printf("Title: "); puts(title); is stupid, when there's printf("Title: %s\n", title); but apparently it failed cause you don't know about C-strings. You don't know about arrays. You don't know Stream I/O, how file pointers behave after read/write. You don't know C.
You cannot develop programs by second guessing what the statements you type perform.
Honestly, why do you guys insist on using C?

I take it you're a linux user..


I only added the write to year[4] because it was printing the year string wrong without it, and my statement seemed to put the null character in the right spot despite element 4 not being declared. I know how arrays work (an array with 4 elements has element 0-3...). I'm still learning stream I/O and some more in depth stuff about file pointers. I just figured getting some answers from people about specific questions would speed up my learning process.

Edited 5 Years Ago by ChEeZeBaLL: n/a

Anyway...

Yeah that was stupid to use printf and puts like that, quite redundant :)


Here is my updated code:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char title[30];
    char artist[30];
    char album[30];
    char year[4];
    char comment[30];
    FILE *fp;

         //OPEN FILE
         fp = fopen("test.mp3", "rb");
         
         //SEEK BACK -125 BYTES
         fseek(fp, -125, SEEK_END);
         
         
         
         //READ AND PRINT TITLE
         fread(title, 30, 1, fp);           
         printf("Title: %s\n", title);
         
         
         //READ AND PRINT ARTIST
         fread(artist, 30, 1, fp);      
         printf("Artist: %s\n", artist);
         
         
         //READ AND PRINT ALBUM
         fread(album, 30, 1, fp);             
         printf("Album: %s\n", album);
         
         
         //READ AND PRINT YEAR
         fread(year, 4, 1, fp);               
         printf("Year: %s\n", year);
         
         
         //READ AND PRINT COMMENT
         fread(comment, 30, 1, fp);         
         printf("Comment: %s\n", comment);
         


         //CLOSE FILE
         fclose(fp);


    printf("\n\n\n");
    system("pause");
    return 0;

//END MAIN
}

The resulting program still looks like this:

http://dl.dropbox.com/u/3679894/SN1.JPG


I don't understand why the year string would print any different from the others. The only difference is the length (4 characters instead of 30). Could the fact that it contains numbers instead of letters possibly have something to do with it?

The only problem with your year string is that it doesn't have a terminating null. It's not stored in the file as a C string, but rather as a set of four characters. The same goes for your other strings, but you are fortunate enough that they happen to be filled with nulls.

You can change the printf statements to use %c conversion instead of %s, or you can make the strings you read in one character wider and explicitly initialize them all to nulls. Since the final NULL never gets written, they will always be properly terminated.

This article has been dead for over six months. Start a new discussion instead.