2016-06-30 89 views
-2

所以我有一個文件,我必須加載一些曲目,找到超過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功能,我真的不知道如何複製結構成員我想從源結構到目標結構,我只設法複製所有成員f從一個結構到另一個結構。 我的n計數器正確計數磁道數,而我的計算bpm的函數似乎可行,但我不知道如何獲得我想要的確切數據。 我嘗試使用memcpy函數,試圖像這樣分配的:longSongs[i]=all[i],我試圖手動分配值,e.g:

longSongs->tracks[i]->mm = all->tracks[i]->mm; 
longSongs->tracks[i]->ss = all->tracks[i]->ss; 
longSongs->tracks[i]->bpm = all->tracks[i]->bpm; 

但沒有任何工程,它總是將源結構的所有成員,無視我的if語句。

+0

爲什麼你不想複製整個'Track'結構? – Barmar

+0

順便說一下,使用兩個'if()'語句來比較時間並不是最好的。只需結合分鐘和秒:'total_secs = mm * 60 + ss'' – Barmar

+0

我確實想複製整個曲目結構(曲目名稱,mm,ss,bpm)。我不想將包含文件中所有歌曲的整個播放列表結構複製到我的結構中,我只想從播放列表中複製那些包含持續時間超過3:30的所有歌曲的歌曲。 – nidau00

回答

0

您不需要複製成員,只需複製指針即可。

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

注意,索引longSongs->tracksn,不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變量,我通過簡化分秒組合成只是總秒數比較運行時間。

+0

非常感謝! – nidau00

相關問題