将特定结构成员复制到另一个结构

时间:2016-06-30 23:34:33

标签: c struct copy

所以我有一个文件,我必须加载一些曲目,找到超过3:30的曲目并找到这些曲目的平均bpm。

这是我的代码。

主档案:

#include <stdio.h>  
#include "functions.h"
int main(void)
{
   Playlist *all, *long_tracks;
   float avg_bpm;
   all = load_tracks("tracks.txt");
   long_tracks = get_tracks_longer_than(3,30,all);
   print_playlist(long_tracks);
   avg_bpm = get_avg_bpm(long_tracks);

   printf("Average BPM of the playlist is: %.2f\n", avg_bpm);

   return 0;
}

标题:

#ifndef FUNCTIONS_H
#define FUNCTIONS_H 

typedef struct track {
char track[250];
float bpm;
int mm, ss;
} Track;

typedef struct playlist {
int count;
Track **tracks;
} Playlist;


void print_playlist(Playlist *list);
Playlist* load_tracks(char *filename);
Playlist* get_tracks_longer_than(int mm, int ss, Playlist* all);
float get_avg_bpm(Playlist *list);

#endif

功能:

#include <stdio.h>  
#include <stdlib.h>
#include <string.h>
#include "functions.h"


void print_playlist(Playlist *list) {
  int i;
  for (i = 0; i < list->count; i++) {
    printf("%s (%d:%d) [%f]\n", list->tracks[i]->track, list->tracks[i]->mm, list->tracks[i]->ss, list->tracks[i]->bpm);
  }
}

Playlist* load_tracks(char *filename) {
  int n,i;
  Playlist *list = (Playlist*) malloc(sizeof(Playlist));
  Track *tracks;

  FILE *f = fopen(filename, "r");
  fscanf(f, "%d", &n);
  printf("Tracks: %d\n", n);

  tracks = (Track*) malloc(n*sizeof(Track));
  list->tracks = (Track**) malloc(n*sizeof(Track*));

  for (i = 0; i < n; i++) {
    fscanf(f, "%d:%d", &tracks[i].mm, &tracks[i].ss);
    fscanf(f, "%f", &tracks[i].bpm);
    fgetc(f);
    fgets(tracks[i].track, 250, f);
    tracks[i].track[strlen(tracks[i].track)-1] = '\0'; 
    list->tracks[i] = &tracks[i];
  }


  list->count = n;
  return list;
}

Playlist* get_tracks_longer_than(int mm, int ss, Playlist* all) {
    Playlist *longSongs = (Playlist*) malloc(sizeof(Playlist));

    Track *tracks;
    tracks = (Track*) malloc(all->count*sizeof(Track));
    longSongs->tracks = (Track**) malloc(all->count*sizeof(Track*));

    int i, n = 0;

    for(i=0;i<all->count;i++)
    {

        if(all->tracks[i]->mm>mm)
        {
            n++;
            memcpy ( &longSongs, &all, sizeof(all) ); //I also tried longSongs[i]=all[i];
        }
        else if(all->tracks[i]->mm==mm)
        {
            if(all->tracks[i]->ss>ss)
            {
            n++;
            memcpy ( &longSongs, &all, sizeof(all) );
            }
        }
    }

    longSongs->count=n;
    return longSongs;
}

float get_avg_bpm(Playlist *list) {
    float avg_bpm=0;
    int i;

    for(i=0;i<list->count;i++)
    {
        avg_bpm+=list->tracks[i]->bpm;
    }

    return avg_bpm/=list->count;

}

问题在于我的get_tracks_longer_than函数,我不知道如何将我想要的结构成员从源结构复制到目标结构,我只是设法将所有成员从一个结构复制到另一个结构。 我的计数器正确计算了曲目的数量,我的计算bpm的函数似乎有效,但我不知道如何获得我想要的确切数据。 我尝试使用memcpy函数,尝试像这样分配它:{​​{1}},我尝试手动分配值,例如:

longSongs[i]=all[i]

但没有任何作用,它总是复制源结构的所有成员,忽略我的if语句。

1 个答案:

答案 0 :(得分:0)

您不需要复制成员,只需复制指针即可。

longSongs->tracks[n] = all->tracks[i];

请注意,longSongs->tracks的索引为n,而不是i。否则,您将在longSongs->tracks数组中为所有未被选中的歌曲留下空白。

Playlist* get_tracks_longer_than(int mm, int ss, Playlist* all) {

    int min_secs = mm*60 + ss;

    Playlist *longSongs = malloc(sizeof(Playlist));
    longSongs->tracks = malloc(all->count*sizeof(Track*));

    int i, n = 0;

    for(i=0;i<all->count;i++)
    {
        if(all->tracks[i]->mm*60 + all->tracks[i]->ss > min_secs)
        {
            longSongs->tracks[n++] = all->tracks[i];
        }
    }

    longSongs->count=n;
    return longSongs;
}

其他更改:我删除了未使用的tracks变量,并通过将分钟和秒组合成几秒来简化比较运行时间。