kuntilanak
asked on
struct question
what is wrong with the following code?
seems like when I do :
song->artist = temp->artist;
and so on it fails
seems like when I do :
song->artist = temp->artist;
and so on it fails
typedef struct Songs
{
char title[20], artist[20], album[20], genre[20], duration[6];
int year;
struct Song *next_song;
} Song;
Song* temp = head_p;
Song* song = (Song*) malloc(sizeof(Song));
song->artist = temp->artist;
song->title = temp->title;
song->album = temp->album;
song->genre = temp->genre;
song->duration = temp->duration;
song->year = temp->year;
>> is the correct way to do something like:
That's indeed what you need to do for strings :)
That's indeed what you need to do for strings :)
btw, I assume that head_p is pointing to a valid Song struct ? And that the error you mentioned was a compile time error, and not a runtime error ?
ASKER
>>btw, I assume that head_p is pointing to a valid Song struct ? And that the error you mentioned was a >>compile time error, and not a runtime error ?
true... now I have just one more error at the very end of my code.. after main returns 0.. it says
I hate this kind of error as it can be anywhere
true... now I have just one more error at the very end of my code.. after main returns 0.. it says
I hate this kind of error as it can be anywhere
ece.c:354: error: syntax error at end of input
That probably means a missing ; somewhere or an unmatched { or something similar. If you don't find it yourself, can you post your entire code here ?
ASKER
yes.. thank you infinity..
#include <stdio.h>
#include <string.h>
typedef struct Songs
{
char title[20], artist[20], album[20], genre[20], duration[6];
int year;
struct Song *next_song;
} Song;
FILE *input, *output;
Song *head_p, *temp, *current = NULL;
int numberOfSongs = 0;
void printSong(Song* song){
printf("Title : %s\n", song->title);
printf("Artist : %s\n", song->artist);
printf("Album : %s\n", song->album);
printf("Duration : %s\n", song->duration);
printf("Genre : %s\n", song->genre);
printf("Year : %d\n",song->year);
}
Song* insertDeleteInterface(){
Song* new_song = (Song*) malloc(sizeof(Song));
printf("Please enter a song title: ");
scanf("%s", new_song->title);
printf("\nPlease enter a song artist: ");
scanf("%s", new_song->artist);
printf("\nPlease enter a song album: ");
scanf("%s", new_song->album);
printf("\nPlease enter a song genre: ");
scanf("%s", new_song->genre);
printf("\nPlease enter a song duration: ");
scanf("%s", new_song->duration);
printf("\nPlease enter a song year: ");
scanf("%d", new_song->year);
return new_song;
}
void insertSong(void){
current->next_song = (Song*)insertDeleteInterface();
numberOfSongs++;
}
void deleteSong(Song* song){
Song* temp = head_p;
Song* prev = NULL;
while (temp != NULL){
if ((strcmp(temp->artist, song->artist) == 0) && (strcmp(temp->title, song->title) == 0) && (strcmp(temp->album, song->album) == 0) && (strcmp(temp->genre, song->genre) == 0) && (strcmp(temp->duration, song->duration) == 0) && (temp->year == song->year)){
prev->next_song = temp->next_song;
free(*song);
}
prev = temp;
temp = (Song*)temp->next_song;
}
}
void exportDatabase(void){
output = fopen("database.dat", "w");
Song* temp = head_p;
while (temp != NULL){
fprintf(output, "%s %s %s %s %s %d\n", temp->title, temp->artist,
temp->album, temp->genre, temp->duration, temp->year);
temp = head_p->next_song;
}
}
void printDatabase(void){
Song* temp = head_p;
while(temp != NULL){
printSong(temp);
temp = head_p->next_song;
}
}
void searchByDatabase(void){
/*sortByTitle();*/
int choice = -1;
char artist[20], title[20], album[20], duration[20], genre[10];
int year;
while ( choice < 1 || choice > 6){
printf("How do you want to search for songs?\n");
printf("1. Artist\n");
printf("2. Title\n");
printf("3. Album\n");
printf("4. Genre\n");
printf("5. Duration\n");
printf("6. Year\n");
scanf("%d", &choice);
}
Song* temp = head_p;
switch(choice){
case 1:
printf("Please enter an artist name: ");
scanf("%s", artist);
while (temp != NULL){
if (strcmp(temp->artist, artist) == 0)
printSong(temp);
temp = temp->next_song;
}
break;
case 2:
printf("Please enter a title name: ");
scanf("%s", title);
while (temp != NULL){
if (strcmp(temp->title, title) == 0)
printSong(temp);
temp = temp->next_song;
}
break;
case 3:
printf("Please enter an album name: ");
scanf("%s", album);
while (temp != NULL){
if (strcmp(temp->album, album) == 0)
printSong(temp);
temp = temp->next_song;
}
break;
case 4:
printf("Please enter a genre: ");
scanf("%s", genre);
while (temp != NULL){
if (strcmp(temp->genre, genre) == 0)
printSong(temp);
temp = temp->next_song;
}
break;
case 5:
printf("Please enter a duration time: ");
scanf("%s", duration);
while (temp != NULL){
if (strcmp(temp->duration, duration) == 0)
printSong(temp);
temp = temp->next_song;
}
break;
case 6:
printf("Please enter the song's year: ");
scanf("%s", year);
while (temp != NULL){
if (strcmp(temp->year, year) == 0)
printSong(temp);
temp = temp->next_song;
}
break;
default:
printf("Invalid input!");
}
}
void sortByTitle(){
}
void sortDatabase(void){
int i, j, result;
int choice = -1;
Song arrayDatabase[numberOfSongs];
while (choice < 0 || choice > 6){
printf("Select an attributes to sort the database (number)\n");
printf("1. Artist\n");
printf("2. Title\n");
printf("3. Album\n");
printf("4. Genre\n");
printf("5. Duration\n");
printf("6. Year\n");
printf("Enter your choice: ");
scanf("%d", &choice);
}
for (i = 0; i < numberOfSongs; i++){
Song* temp = head_p;
Song* song = (Song*) malloc(sizeof(Song));
memcpy(song->artist, temp->artist, 20);
memcpy(song->title, temp->title, 20);
memcpy(song->album ,temp->album, 20);
memcpy(song->genre ,temp->genre, 20);
memcpy(song->duration, temp->duration, 6);
song->year = temp->year;
memcpy(&(arrayDatabase[i]), song, sizeof(Song));
}
for (i=0; i<numberOfSongs-1; i++) {
for (j=0; j<numberOfSongs-1-i; j++){
if (choice == 1)
result = strcmp(arrayDatabase[j+1].artist, arrayDatabase[j].artist);
else if (choice == 2)
result = strcmp(arrayDatabase[j+1].title, arrayDatabase[j].title);
else if (choice == 3)
result = strcmp(arrayDatabase[j+1].album, arrayDatabase[j].album);
else if (choice == 4)
result = strcmp(arrayDatabase[j+1].genre, arrayDatabase[j].genre);
else if (choice == 5)
result = strcmp(arrayDatabase[j+1].duration, arrayDatabase[j].duration);
else
result = arrayDatabase[j+1].year < arrayDatabase[j].year;
if (result < 0) {
/* swap a[j] and a[j+1] */
Song* tmp = (Song*) malloc(sizeof(Song));
memcpy(tmp, &arrayDatabase[j], sizeof(Song));
memcpy(&arrayDatabase[j], &arrayDatabase[j+1], sizeof(Song));
memcpy(&arrayDatabase[j+1],tmp, sizeof(Song));
}
}
}
temp = head_p;
i = 0;
while(temp != NULL){
memcpy(temp->title, &arrayDatabase[i].title, 20);
/*
temp->artist = arrayDatabase[i].artist;
temp->genre = arrayDatabase[i].genre;
temp->year = arrayDatabase[i].year;
temp->duration = arrayDatabase[i].duration;
temp->duration = arrayDatabase[i].album;
temp = temp->next_song;
*/
i++;
}
}
void deleteByDatabase(void){
int choice = -1;
char artist[20], title[20], album[20], genre[20], duration[20], year[4];
while (choice < 0 || choice > 6){
printf("Select an attribute to delete from the database, please enter a number\n");
printf("1. Artist\n");
printf("2. Title\n");
printf("3. Album\n");
printf("4. Genre\n");
printf("5. Duration\n");
printf("6. Year\n");
printf("Enter your choice: ");
scanf("%d", &choice);
}
Song* temp = head_p;
switch(choice){
case 1:
printf("Please enter an artist name:");
scanf("%s", artist);
case 2:
printf("Please enter a title:");
scanf("%s", title);
case 3:
printf("Please enter an album name:");
scanf("%s", album);
case 4:
printf("Please enter a genre:");
scanf("%s", genre);
case 5:
printf("Please enter a duration");
scanf("%s", duration);
case 6:
printf("Please enter a year:");
scanf("%d", year);
default:
printf("Error in choice!\n");
while (temp != NULL){
if (choice == 1 && strcmp(temp->artist, artist) == 0)
deleteSong(temp);
else if (choice == 2 && strcmp(temp->title, title) == 0)
deleteSong(temp);
else if (choice == 3 && strcmp(temp->album, album) == 0)
deleteSong(temp);
else if (choice == 4 && strcmp(temp->genre, genre) == 0)
deleteSong(temp);
else if (choice == 5 && strcmp(temp->duration, duration) == 0)
deleteSong(temp);
else if (choice == 6 && strcmp(temp->year, year) == 0)
deleteSong(temp);
temp = temp->next_song;
}
}
int main(void)
{
input = fopen("music.dat", "r");
char delete[20];
int choice = -1;
while (!feof(input)){
Song* temp = (Song*)malloc(sizeof(Song));
fscanf(input, "%s%s%s%s%s%d", temp->title, temp->artist, temp->album, temp->genre, temp->duration, temp->year);
numberOfSongs++;
if (current == NULL)
head_p = temp;
else
current->next_song = temp;
current = temp;
temp->next_song = NULL;
}
while(choice!=7)
{
printf("Welcome to your cTunes interface.\n");
printf("What do you want to do?\n");
/*
printf("1. Insert songs into database\n2. Delete songs from the
database\n3. Export your database to a file\n4. Sort the songs in the
database\n5. Search for songs by a certain attribute\n
6. delete all songs of a certain attribute\n7. Exit the program\n");
*/
scanf("%c", &choice);
}
switch(choice){
case 1://insert song
insertSong();
break;
case 2://delete function
deleteSong(insertDeleteInterface());
break;
case 3:
printDatabase();
break;
case 4://sort songs
sortDatabase();
break;
case 5://search by attribute
searchByAttribute();
break;
case 6://delete by attribute
deleteByAttribute();
break;
case 7:
printf("Goodbye, come again soon.\n");
break;
default:
printf("Invalid choice.\n");
}
return 0;
}
hi,
correct,
you have 2 storage area (dynamic or not)
if you do
song->artist = temp->artist
you overwrite the address of the first buffer with the second.
If you had
Struct Song1,Song2
you could do
Song1=Song2
But you cannot becouse you are using lists an then dynamic areas.
To minimize coding and errors I'ld do in this way:
1) malloc the structure
2) cast type Song* to char* and do a massive copy
memcpy( (char*)song, (char*)temp, sizeof(struct Song))
3) adjust the differences using correclty pSong* pointer
song->next_song = .....
song->other = x++
memcpy( song->..., ...., ....)
bye
vic
correct,
you have 2 storage area (dynamic or not)
if you do
song->artist = temp->artist
you overwrite the address of the first buffer with the second.
If you had
Struct Song1,Song2
you could do
Song1=Song2
But you cannot becouse you are using lists an then dynamic areas.
To minimize coding and errors I'ld do in this way:
1) malloc the structure
2) cast type Song* to char* and do a massive copy
memcpy( (char*)song, (char*)temp, sizeof(struct Song))
3) adjust the differences using correclty pSong* pointer
song->next_song = .....
song->other = x++
memcpy( song->..., ...., ....)
bye
vic
ASKER
erhmm.. yes the struct thing is resolved.. there's one error in the code I pasted above... don't know where it is
The switch in the deleteByDatabase function is missing the closing }
ASKER
thanks for pointing that out
So, does it work better now ?
ASKER
it does except I got the following warnings:
the insertDeleteInterface() function returns a Song*, so I don't know why it gives me that error
the insertDeleteInterface() function returns a Song*, so I don't know why it gives me that error
ece.c: In function `insertSong':
ece.c:45: warning: assignment from incompatible pointer type
current->next_song = (Song*)insertDeleteInterface();
You don't need the cast to Song* because that's what insertDeleteInterface returns anyway. But I don't think that's what's giving you the warning.
I'd suggest changing the declaration of next_song from "struct Song *" to "struct Songs *", since Song is a typedef for struct Songs and it hasn't even been defined yet at the point of declaration. If you substitute "struct Songs" for "Song" with the current code, you would get "struct struct Songs *", which doesn't make any sense.
I'd suggest changing the declaration of next_song from "struct Song *" to "struct Songs *", since Song is a typedef for struct Songs and it hasn't even been defined yet at the point of declaration. If you substitute "struct Songs" for "Song" with the current code, you would get "struct struct Songs *", which doesn't make any sense.
ASKER
I'll try to do that and see if it helps
ASKER
Ok, just one more problem that needs to be fixed:
ece.c: In function `deleteByAttribute':
ece.c:287: warning: comparison between pointer and integer
temp->year == year
That's code you haven't posted. I can't tell what's the pointer and what's the integer, but the compiler is probably right to warn you. Could you supply some context? Not necessarily your whole program, but maybe the whole function. The declarations of temp and year are especially important.
ASKER
it's actually the line 289 on my original code I posted above.. however as year is not a str so therefore I can't use strcmp and therefore I just compare it directly... and that's what I did....
it should say:
if (temp->year == year)
it should say:
if (temp->year == year)
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
thanks for pointing that out
ASKER
Open in new window