Cześć,
piszę program, który ma między innymi pobrać dane z pliku. txt i zapisać je do listy jednokierunkowej. W 3/4 przypadków działa to bez zarzutu jednak czasem program kończy się błędem zgłaszając wyjście poza zakresy pamięci(1) lub wpisuje w listę losowe dane(2).
1:
2: (w performer powinno być Fisz).
Niżej umieszczam kod. Przepraszam za bałagan, ale program jest jeszcze "rozgrzebany" i inne funkcjonalności (nie te związane z wczytaniem pliku) są zaimplementowane na pół gwizdka.
KOD:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <string.h>
struct Songs {
char *label;
char *name;
char *performer;
int time;
char *localization;
struct Songs *next;
};
struct Songs *head;
void help();
void insert(char *lbl, char *name, char *performer, int time, char *localization);
void display();
void read_file(char *file_name);
int parse_to_time(char *time);
void sort_by_time();
void sort_by_name();
void swap(struct Songs *a, struct Songs *b);
size_t getline(char **lineptr, size_t *n, FILE *stream);
int main(int argc, char **argv) {
read_file("songs.txt");
sort_by_name();
display();
free(head);
return 0;
}
void help() {
printf("-i input file with music\n");
printf("-p playlist file\n");
printf("-c time sort\n");
printf("-w performer sort\n");
printf("-t title sort\n");
exit(1);
}
void insert(char *lbl, char *name, char *performer, int time, char *localization) {
struct Songs *ptr, *temp;
ptr = (struct Songs *) malloc(sizeof(struct Songs));
if (ptr == NULL) printf("OVERFLOW\n");
else {
ptr->label = lbl;
ptr->name = name;
ptr->performer = performer;
ptr->time = time;
ptr->localization = localization;
if (head == NULL) {
ptr->next = NULL;
head = ptr;
} else {
temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = ptr;
ptr->next = NULL;
}
}
}
void display() {
struct Songs *ptr;
ptr = head;
if (ptr == NULL) printf("Nothing to print\n");
else {
while (ptr != NULL) {
printf("Label:\t\t%s\n"
"Name:\t\t%s\n"
"Performer:\t%s\n"
"Time:\t\t%d\n"
"Localization:\t%s\n\n", ptr->label, ptr->name, ptr->performer, ptr->time, ptr->localization);
ptr = ptr->next;
}
}
}
void read_file(char *file_name) {
FILE *fp;
char *line = NULL;
size_t len = 0;
size_t read;
int line_counter = 0;
char *element[5];
fp = fopen(file_name, "r");
if (fp == NULL) printf("Empty file!");
while ((read = getline(&line, &len, fp)) != EOF) {
//if line in file is empty skip loop step
if (strcmp(line, "\n") == 0) continue;
//delete line break
line[strcspn(line, "\n")] = 0;
//allocate memory to string, copy line to array of strings
element[line_counter] = (char *) malloc(sizeof(line));
strcpy(element[line_counter], line);
line = NULL;
line_counter++;
//if collected five values, insert it to a list
if (line_counter > 4) {
line_counter = 0;
insert(element[0], element[1], element[2], parse_to_time(element[3]), element[4]);
}
}
printf("\n\n");
fclose(fp);
if (line) free(line);
}
int parse_to_time(char *time) {
int minutes, seconds;
char *seconds_str;
//takes seconds only
strncpy(seconds_str, time + (strlen(time) - 2), 2);
//take minutes only
strtok(time, ":");
minutes = atoi(time) * 60;
seconds = atoi(seconds_str);
return minutes + seconds;
}
void sort_by_time() {
int swapped, i;
struct Songs *ptr1;
struct Songs *lptr = NULL;
/* Checking for empty list */
if (head == NULL)
return;
do {
swapped = 0;
ptr1 = head;
while (ptr1->next != lptr) {
if (ptr1->time > ptr1->next->time) {
swap(ptr1, ptr1->next);
swapped = 1;
}
ptr1 = ptr1->next;
}
lptr = ptr1;
} while (swapped);
}
void sort_by_name() {
int swapped;
struct Songs *ptr;
struct Songs *lptr = NULL;
/* Checking for empty list */
if (head == NULL)
return;
do {
swapped = 0;
ptr = head;
while (ptr->next != lptr) {
if (ptr->name[0] > ptr->next->name[0]) {
swap(ptr, ptr->next);
swapped = 1;
}
ptr = ptr->next;
}
lptr = ptr;
} while (swapped);
}
void swap(struct Songs *a, struct Songs *b) {
char *temp_lbl = a->label;
a->label = b->label;
b->label = temp_lbl;
char *temp_name = a->name;
a->name = b->name;
b->name = temp_name;
char *temp_perf = a->performer;
a->performer = b->performer;
b->performer = temp_perf;
int temp_time = a->time;
a->time = b->time;
b->time = temp_time;
char *temp_localization = a->localization;
a->localization = b->localization;
b->localization = temp_localization;
}
size_t getline(char **lineptr, size_t *n, FILE *stream) {
char *bufptr = NULL;
char *p = bufptr;
size_t size;
int c;
if (lineptr == NULL) {
return -1;
}
if (stream == NULL) {
return -1;
}
if (n == NULL) {
return -1;
}
bufptr = *lineptr;
size = *n;
c = fgetc(stream);
if (c == EOF) {
return -1;
}
if (bufptr == NULL) {
bufptr = malloc(128);
if (bufptr == NULL) {
return -1;
}
size = 128;
}
p = bufptr;
while (c != EOF) {
if ((p - bufptr) > (size - 1)) {
size = size + 128;
bufptr = realloc(bufptr, size);
if (bufptr == NULL) {
return -1;
}
}
*p++ = c;
if (c == '\n') {
break;
}
c = fgetc(stream);
}
*p++ = '\0';
*lineptr = bufptr;
*n = size;
return p - bufptr - 1;
}
Plik z danymi:
Met1
Master of Puppets
Metalica
8:36
c:/muzyka/mmofp.mp3
Dod1
Nie daj sie
Doda
3:01
c:/muzyka/pop/doda1.mp3
Tac1
4 AM in Girona
Taco Hemingway
3:09
c:/muzyka/4am.mp3
Fis1
Czerowna sukienka
Fisz
5:35
c:/muzyka/idk/czer.mp3
Sub1
Cradles
Sub Urban
3:30
c:/muzyka/idk/sub_urban_cradles.mp3
Jai1
Dynabeat
Jain
2:53
c:/muzyka/idk/dynabeat.mp3
Byłbym wdzięczny za pomoc, na ten moment nie widzę co jest nie tak.
UPDATE: widzę że program spada z rowerka kiedy ma w tekstowym więcej niż 4 piosenki ¯\_(ツ)_/¯.