Thread: Error Reading Track from ID3V1 Tag

  1. #1
    Registered User
    Join Date
    Feb 2015
    Posts
    1

    Error Reading Track from ID3V1 Tag

    I am currently trying to read information from an ID3V1.1 tag in C. For this project we are not allowed to use any external libraries. All of the fields except for the track field read correctly. The last two lines are the ones giving me trouble. Whenever I run the program, I get a seg fault when it tries to get the track number. I tried to debug using gdb and it said the problem was happening on line 34 which is where the fseek is. It works for the other fields so I'm wondering why it is going wrong. Should I change the offset to something other than -128? But the whole tag is only 128 characters so I'm unsure what is going wrong. Thanks in advance. Here's the code and the debug message:
    Code:
    Program received signal SIGSEGV,
        Segmentation fault.0x00000034ff66edf1 in fseek() from / lib64 /
        libc.so .6 Missing separate debuginfos,
        use:debuginfo - install glibc - 2.12 - 1.132.el6_5 .3.x86_64(gdb) back
    #0  0x00000034ff66edf1 in fseek () from /lib64/libc.so.6
    #1  0x000000000040076f in main (argc=1, argv=0x7fffffffdf58) at id3tagEd.c:34
    Code:
    Code:
    #include<stdio.h>
    #include<string.h>
    
    structTag {
      char tag[3];
      char song_title[30];
      char artist[30];
      char album[30];
      char year[4];
      char comment[28];
      char seperator;
      char track;
      char genre;
    };
    
    int main(int argc, char *argv[])
    {
      structTag file_tag;
      FILE *fp;
      char title[31];
      char artist[31];
      char album[31];
      char year[5];
      char comment[29];
      char track[2];
      int track_number;
    
      fp = fopen(argv[1], "r+b");
      if (!fp) {
        printf("File does not exist");
      }
      fseek(fp, -128, SEEK_END);
      fread(&file_tag, sizeof(file_tag), 1, fp);
      fclose(fp);
      if (strncmp(file_tag.tag, "TAG", 3) != 0) {
        printf("ID3 tag is not present\n");
      } else {
        strncpy(title, file_tag.song_title, 30);
        title[31] = '\0';
        printf("Title: %s\n", title);
        strncpy(artist, file_tag.artist, 30);
        artist[31] = '\0';
        printf("Artist: %s\n", artist);
    
        strncpy(album, file_tag.album, 30);
        album[31] = '\0';
        printf("Album: %s\n", album);
    
        strncpy(year, file_tag.year, 4);
        year[4] = '\0';
        printf("Year: %s\n", year);
        //printf("Year: %.4s\n",file_tag.year);
    
        strncpy(comment, file_tag.comment, 28);
        comment[29] = '\0';
        printf("Comment: %s\n", comment);
        //these lines cause the seg fault
        track_number = atoi(file_tag.track);
        printf("Track: %d\n", track_number);
    
      }
      return0;
    }
    Last edited by Salem; 02-08-2015 at 01:23 AM. Reason: fixed all the formatting

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,662
    > #1 0x000000000040076f in main (argc=1, argv=0x7fffffffdf58)
    If the argc is accurate here, then you didn't supply a filename argument to your program.

    > fp = fopen(argv[1], "r+b");
    Which means this accessed what?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Sep 2014
    Posts
    364
    I don't know how the ID3v1-Tag looks like, so I hope your struct is right.
    But if the track and genre is really only 1 byte, then i think it is not a character.
    It looks for me that this are uint8_t (integers that use 1 byte).
    Please check this.

    BTW, you check if the file was successfully opened.
    If it is not, you trow a message, but continue. This is problematic.
    And, as Salem pointed out, why you open the file with "r+b"?
    You only read the file, not writing. The mode "rb" is enough.
    The check should look like this:
    Code:
    …
      if (!fp) {
        printf("File does not exist");
        return 1;
      }
    …
    or in combination with open
    Code:
    …
      if ((fp = fopen(argv[1], "rb")) == NULL) {
        printf("File does not exist");
        return 1;
      }
    …
    At the declatation of the struct I miss a space, but I think this is a failure from copy&paste.
    Other have classes, we are class

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. On the right track?
    By JayCee++ in forum C++ Programming
    Replies: 17
    Last Post: 10-07-2011, 01:30 PM
  2. Modifying MP3 tags (ID3v1)
    By yourbuddypal in forum C++ Programming
    Replies: 5
    Last Post: 07-18-2006, 11:12 AM
  3. ID3v1 /ID3v2 Tags @ mp3s
    By Kordanor in forum Tech Board
    Replies: 15
    Last Post: 12-03-2003, 07:02 AM
  4. Am I on the right track
    By romeoz in forum C++ Programming
    Replies: 12
    Last Post: 07-07-2003, 10:10 PM
  5. not on right track
    By Dena in forum C++ Programming
    Replies: 1
    Last Post: 02-23-2002, 07:03 PM