2016-06-30 6 views
-2

Ich habe also eine Datei, aus der ich eine Reihe von Tracks laden muss, finde Tracks länger als 3:30 und finde den durchschnittlichen BPM dieser Tracks.Kopieren bestimmter Strukturelemente in eine andere Struktur

Hier ist der Code, den ich habe.

Hauptdatei:

#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; 
} 

Rubrik:

#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 

Funktionen:

#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; 

} 

Problem ist in meiner get_tracks_longer_than Funktion, in der ich nicht wirklich wissen, wie zu kopieren das Strukturelement, das ich von der Quellstruktur zur Zielstruktur haben möchte, konnte ich nur alle Mitglieder f kopieren von einer Struktur zur anderen. Mein n-Counter zählt die Anzahl der Tracks korrekt, und meine Funktion, die bpm berechnet, scheint zu funktionieren, aber ich weiß nicht, wie ich die genauen Daten bekommen soll. Ich versuchte Memcpy Funktion, versucht es, wie diese Zuordnung: longSongs[i]=all[i], und ich versuchte, manuell Werte zuweisen, z:

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

aber nichts funktioniert, ist es immer kopiert alle Mitglieder der Quellstruktur, meine if-Anweisungen ignoriert.

+0

Warum möchten Sie nicht die gesamte "Track" -Struktur kopieren? – Barmar

+0

BTW, mit zwei 'if()' Anweisungen zum Vergleichen der Zeiten ist nicht am besten. Kombinieren Sie einfach die Minuten und Sekunden: 'total_secs = mm * 60 + ss;' – Barmar

+0

Ich möchte die gesamte Spurstruktur kopieren (Titelname, mm, ss, bpm). Ich möchte nicht die gesamte Playlist-Struktur, die alle Songs in der Datei enthält, in meine Struktur kopieren. Ich möchte nur diese Songs aus der Playliste kopieren, die alle Songs enthält, deren Dauer 3:30 überschreitet. – nidau00

Antwort

0

Sie müssen die Mitglieder nicht kopieren, kopieren Sie einfach die Zeiger.

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

Beachten Sie, dass der Index in longSongs->tracksn ist, nicht i. Andernfalls bleiben im Array longSongs->tracks Lücken für alle nicht ausgewählten Songs.

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; 
} 

Weitere Änderungen: entfernte ich die ungenutzten tracks Variable, und ich vereinfachte die Laufzeiten zu vergleichen nach Minuten und Sekunden in nur insgesamt Sekunden kombiniert.

+0

Vielen Dank! – nidau00