当前时区为 UTC + 8 小时



发表新帖 回复这个主题  [ 5 篇帖子 ] 
作者 内容
1 楼 
 文章标题 : [求助]编译通过,执行出现"段错误"(含源代码)
帖子发表于 : 2006-05-13 14:34 
头像

注册: 2006-04-22 10:50
帖子: 116
地址: Mito
送出感谢: 0 次
接收感谢: 0 次
先说此程序的用途:

由于libmtp自带的sendtr,向Zen Vision:M传输mp3时,必须手动输入该mp3的tag信息才行,因此我拼了这个程序,大部分是将Taglib的tagreader_c.c和libmtp的sendtr.c的代码拼在一起而已。然后进行了一些调整。

gcc编译通过,没有任何警告
gcc -g -I/usr/local/include/ -I/usr/local/include/taglib -lmtp -ltag_c loadtrack.c -o loadtrackc

执行时,到打印输出年份那行之后就出现段错误。

由于这是我头一次在linux下写C程序,再加上C也是有两年没好好写过东西了,所以一时间也不知道该怎么办,只好求助各位高手。

以下是我的程序的loadtrack.c的源代码:
代码:
#include <stdio.h>

#include <tag_c.h>

#ifndef FALSE

#define FALSE 0

#endif



#include <libmtp.h>
#include <string.h>

#include <sys/stat.h>

#ifdef HAVE_LIBGEN_H

#include <libgen.h> /* basename() */

#endif



#ifndef HAVE_LIBGEN_H

//get full file name from path

static char *basename(char *in) {

  char *p;

  if (in == NULL)

    return NULL;

  p = in + strlen(in) - 1;

  while (*p != '\\' && *p != '/' && *p != ':')

    { p--; }

  return ++p;

}

#endif

//get file extention

static char *extname(char *in) {

  char *p;

  if (in == NULL)

    return NULL;

  p = in + strlen(in) - 1;

  while (*p != '.'){ p--; }

  return ++p;

}

//show the usage message

static void usage(void)

{

  fprintf(stderr, "Usage: loadtrack [Option]... <path>\n");

  fprintf(stderr, "Send a track to MTP device.\n");

  fprintf(stderr, "You can specify the tag informations with the [Option] listed below\n");

  fprintf(stderr, "Or you can use this command without any options, and it will use the tag informations in the file itself.\n");

  fprintf(stderr, "\n");

  fprintf(stderr, "\t<path>\t\t\t\tThe path to the track which will be sent.");

  fprintf(stderr, "\n");

  fprintf(stderr, "\t-t <title>\t\t\tSet the title of the track.\n");

  fprintf(stderr, "\t-a <artist>\t\t\tSet the artist\n");

  fprintf(stderr, "\t-l <album>\t\t\tSet the album name\n");

  fprintf(stderr, "\t-g <genre>\t\t\tSet the genre\n");

  fprintf(stderr, "\t-n <track number>\t\tSet the track number.\n");

  fprintf(stderr, "\t-y <year>\t\t\tSet the year.\n");

  fprintf(stderr, "\t-d <duration in seconds>\tSet the duration(seconds).\n");

  fprintf(stderr, "\t-f \"Dest folder name\"\t\tSet the destination folder name in the MTP device.\n");

  fprintf(stderr, "\t\t\t\t\tIf the folder couldn't be found, then create it automatically.\n");

  fprintf(stderr, "\t\t\t\t\tIf didn't specify, then it will use the artist name as the new folder name.\n");

  exit(1);

}

//find the destination folder exists or not

static uint32_t find_folder_list(char *name, LIBMTP_folder_t *folderlist, int level)

{

  uint32_t i;



  if(folderlist==NULL) {

    return 0;

  }



  if(!strcasecmp(name, folderlist->name))

    return folderlist->folder_id;



  if ((i = (find_folder_list(name, folderlist->child, level+1))))

    return i;

  if ((i = (find_folder_list(name, folderlist->sibling, level))))

    return i;



  return 0;

}

//send track to device

static void loadtrack(char *path, char *pfolder, LIBMTP_track_t *trackmeta)

{

  uint32_t parent_id = 0;

  struct stat;

  char *lang;

  LIBMTP_mtpdevice_t *device;

  LIBMTP_folder_t *folders = NULL;

  int ret;



  LIBMTP_Init();

  /*

   * Check environment variables $LANG and $LC_CTYPE

   * to see if we want to support UTF-8 unicode

   */

  lang = getenv("LANG");

  if (lang != NULL) {

    if (strlen(lang) > 5) {

      char *langsuff = &lang[strlen(lang)-5];

      if (strcmp(langsuff, "UTF-8")) {

      printf("Your system does not appear to have UTF-8 enabled ($LANG=\"%s\")\n", lang);

      printf("If you want to have support for diacritics and Unicode characters,\n");

      printf("please switch your locale to an UTF-8 locale, e.g. \"en_US.UTF-8\".\n");

      }

    }

  }

 

  device = LIBMTP_Get_First_Device();

  if (device == NULL) {

    printf("No MTP device found.\n");

    LIBMTP_destroy_track_t(trackmeta);

    exit(1);

  }

  // If a folder argument was passed in, try to locate the folder.

  if (pfolder) {

    folders = LIBMTP_Get_Folder_List(device);

    if(folders == NULL) {

      printf("No folders found, creating the folder in root directory...\n");

      parent_id = LIBMTP_Create_Folder(device, pfolder, 0);

     if (parent_id == 0) {

       printf("Folder creation failed.\n");

     } else {

       printf("New folder created with ID: %d\n", parent_id);

     }

    } else {

      parent_id = find_folder_list(pfolder, folders, 0);

      if  (!parent_id) {

      printf("Parent folder could not be found, ignoring folder argument.\n");

      }

    }

  }

 

  printf("Sending track...\n");

  ret = LIBMTP_Send_Track_From_File(device, path, trackmeta, /*progress*/NULL, NULL, parent_id);

  printf("\n");

 

  LIBMTP_Release_Device(device);

 

  printf("New track ID: %d\n", trackmeta->item_id);



  LIBMTP_destroy_track_t(trackmeta);

 

  printf("OK.\n");

}

//main entry

int main(int argc, char *argv[])

{

  TagLib_File *file;

  TagLib_Tag *tag;

  const TagLib_AudioProperties *properties;

  int opt;

  extern int optind;

  extern char *optarg;

 

  char *path, *filename;

  char *partist = NULL;

  char *ptitle = NULL;

  char *pgenre = NULL;

  char *palbum = NULL;

  char *pfolder = NULL;

   

  char *pcodec = NULL;

 

  uint16_t tracknum = 0;

  uint16_t length = 0;

  uint16_t year = 0;

 

  uint64_t filesize;

  struct stat sb;



  taglib_set_strings_unicode(1);

 

  while ( (opt = getopt(argc, argv, "t:a:l:g:n:d:y:f:")) != -1 ) {

    switch (opt) {

    case 't':

      ptitle = strdup(optarg);

      break;

    case 'a':

      partist = strdup(optarg);

      break;

    case 'l':

      palbum = strdup(optarg);

      break;

    case 'g':

      pgenre = strdup(optarg);

      break;

    case 'n':

      tracknum = atoi(optarg);

      break;

    case 'd':

      length = atoi(optarg);

      break;

    case 'y':

      year = atoi(optarg);

      break;

    case 'f':

      pfolder = strdup(optarg);

      break;

    default:

      usage();

    }

  }



  argc -= optind;

  argv += optind;

 

  if ( argc != 1 ) {

    printf("You need to pass a filename.\n");

    usage();

  }

  //printf("******************** File: \"%s\" ********************\n", argv[0]);

 

  path = argv[0];

  //compute file name

  filename = basename(path);

  if (filename == NULL) {

    printf("Error: filename could not be based.\n");

    exit(1);

  }

  printf("Filename:\t%s\n",filename);

  //compute the file extention

  pcodec = extname(path);

  if (pcodec == NULL) {

    printf("Error: file extention couldn't be detected.\n");

    exit(1);

  }

  printf("Codec:\t%s\n",pcodec);

  //compute file size

  if ( stat(path, &sb) == -1 ) {

    fprintf(stderr, "%s: ", path);

    perror("stat");

    exit(1);

  }

  filesize = (uint64_t) sb.st_size;

  //printf("Filesize:\t%d\n",(int)filesize);

  //new tag lib object

  file=taglib_file_new(path);

  //get file tag and properties

  tag = taglib_file_tag(file);

  properties = taglib_file_audioproperties(file);

  //new trackmeta object

  LIBMTP_track_t *trackmeta;

  trackmeta = LIBMTP_new_track_t();



  //track file name and file size

  if (filename != NULL) {

    trackmeta->filename = strdup(filename);

  }

  trackmeta->filesize = filesize;

  //track file type

  if (!strcmp(pcodec,"MP3") || !strcmp(pcodec,"mp3")) {

    trackmeta->filetype = LIBMTP_FILETYPE_MP3;

  }  else if (!strcmp(pcodec,"WAV") || !strcmp(pcodec,"wav")) {

    trackmeta->filetype = LIBMTP_FILETYPE_WAV;

  } else if (!strcmp(pcodec,"WMA") || !strcmp(pcodec,"wma") ||

        !strcmp(pcodec,"ASF") || !strcmp(pcodec,"asf")) {

    trackmeta->filetype = LIBMTP_FILETYPE_WMA;

  } else {

    printf("Not a valid codec: \"%s\"\n", pcodec);

    exit(1);

  }

  //track tag info

  trackmeta->title = ptitle==NULL?taglib_tag_title(tag):strdup(ptitle);

  printf("Title:\t%s\n", trackmeta->title);

  trackmeta->artist = partist==NULL?taglib_tag_artist(tag):strdup(partist);

  printf("Artist:\t%s\n", trackmeta->artist);

  trackmeta->album = palbum==NULL?taglib_tag_album(tag):strdup(palbum);

  printf("Album:\t%s\n", trackmeta->album);

  trackmeta->genre = pgenre==NULL?taglib_tag_genre(tag):strdup(pgenre);

  printf("Genre:\t%s\n", trackmeta->genre);

  trackmeta->tracknumber = tracknum==0?taglib_tag_track(tag):tracknum;

  printf("Track:\t%d\n", trackmeta->tracknumber);

  trackmeta->duration = length==0?taglib_audioproperties_length(properties)*1000:length*1000;

  printf("Length:\t%d\n", trackmeta->duration);

  //track date

  year = year==0?taglib_tag_year(tag):year;

  if (year > 0) {

    char tmp[80];

    printf("Year:\t%d\n", year);

    snprintf(tmp, sizeof(tmp)-1, "%4d0101T0000.0", year);

    tmp[sizeof(tmp)-1] = '\0';

    trackmeta->date = strdup(tmp);

  }

 

  //parent folder

  if (!strlen(pfolder)) {

    printf("Destination folder didn't be specified, use the artist name as default folder name.\n");

   pfolder = trackmeta->artist;

    //usage();

  }

  //free resource

  taglib_tag_free_strings();

  taglib_file_free(file);

  //send

  loadtrack(path, pfolder, trackmeta);

  return 0;

}


运行:
sudo loadtrack /media/WinData/音乐/英语/Linkin\ Park杂集/In\ the\ end\(REMIX\).mp3

终端输出:
代码:
Filename:       In the end(REMIX).mp3
Codec:  mp3
Title:  In the end (REMIX)
Artist: Linkin Park
Album:  Reanimation
Genre:  Alternative Rock
Track:  3
Length: 240000
Year:   2002
段错误

gdb输出:
代码:
Filename:       In the end(REMIX).mp3
Codec:  mp3
Title:  In the end (REMIX)
Artist: Linkin Park
Album:  Reanimation
Genre:  Alternative Rock
Track:  3
Length: 240000
Year:   2002

Program received signal SIGSEGV, Segmentation fault.


_________________
Ubuntu only now on Dell XPS M1710


页首
 用户资料  
 
2 楼 
 文章标题 :
帖子发表于 : 2006-05-13 15:03 
头像

注册: 2005-08-15 0:04
帖子: 1880
地址: 南7技校
送出感谢: 0 次
接收感谢: 0 次
刚在学编译,段错误的提示是比较模糊的,这个有可能是指针越界,也有可能是指针悬空等等。编译能够通过而运行出现这个提示的例子非常的多。gdb调试的时候是可以跟踪到出现问题的这个地方的,这个东西只能自己慢慢研究了,当年c没有学好,到现在也是看到程序就晕。见笑了!


_________________
飞得高,飞得低,学习再学习,多少大秘密!
http://zhan.blog.ubuntu.org.cn


页首
 用户资料  
 
3 楼 
 文章标题 :
帖子发表于 : 2006-05-13 15:04 
头像

注册: 2006-02-27 20:19
帖子: 599
地址: works system
送出感谢: 0 次
接收感谢: 0 次
if (!strlen(pfolder))
这句话有问题
pfolder指向NULL,不能strlen吧,直接改为if(!pfolder)试试


_________________
东西路,南北走
十字路口人咬狗
拿起狗来打砖头
砖头咬了狗一口
图片


页首
 用户资料  
 
4 楼 
 文章标题 :
帖子发表于 : 2006-05-13 15:10 
头像

注册: 2006-04-22 10:50
帖子: 116
地址: Mito
送出感谢: 0 次
接收感谢: 0 次
楼上说的有道理,经楼上的一提点,我也发现了,唉,惭愧,太长时间没弄C了。

等我试试先


_________________
Ubuntu only now on Dell XPS M1710


页首
 用户资料  
 
5 楼 
 文章标题 :
帖子发表于 : 2006-05-13 15:29 
头像

注册: 2006-04-22 10:50
帖子: 116
地址: Mito
送出感谢: 0 次
接收感谢: 0 次
嗯,问题解决了,剩下就是继续修正这个程序了。

传倒是传上去了,不过有点儿问题。

谢谢了


_________________
Ubuntu only now on Dell XPS M1710


页首
 用户资料  
 
显示帖子 :  排序  
发表新帖 回复这个主题  [ 5 篇帖子 ] 

当前时区为 UTC + 8 小时


在线用户

正在浏览此版面的用户:没有注册用户 和 1 位游客


不能 在这个版面发表主题
不能 在这个版面回复主题
不能 在这个版面编辑帖子
不能 在这个版面删除帖子
不能 在这个版面提交附件

前往 :  
本站点为公益性站点,用于推广开源自由软件,由 DiaHosting VPSBudgetVM VPS 提供服务。
我们认为:软件应可免费取得,软件工具在各种语言环境下皆可使用,且不会有任何功能上的差异;
人们应有定制和修改软件的自由,且方式不受限制,只要他们自认为合适。

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
简体中文语系由 王笑宇 翻译