[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 203
  • Last Modified:

struct question

what is wrong with the following code?

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;

Open in new window

0
kuntilanak
Asked:
kuntilanak
  • 10
  • 6
  • 2
  • +1
1 Solution
 
kuntilanakAuthor Commented:
is the correct way to do something like:
 memcpy(song->artist, temp->artist, 20);

Open in new window

0
 
Infinity08Commented:
>> is the correct way to do something like:

That's indeed what you need to do for strings :)
0
 
Infinity08Commented:
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 ?
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
kuntilanakAuthor Commented:
>>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
ece.c:354: error: syntax error at end of input

Open in new window

0
 
Infinity08Commented:
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 ?
0
 
kuntilanakAuthor Commented:
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;
}

Open in new window

0
 
dolomitiCommented:
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


0
 
kuntilanakAuthor Commented:
erhmm.. yes the struct thing is resolved.. there's one error in the code I pasted above... don't know where it is
0
 
Infinity08Commented:
The switch in the deleteByDatabase function is missing the closing }
0
 
kuntilanakAuthor Commented:
thanks for pointing that out
0
 
Infinity08Commented:
So, does it work better now ?
0
 
kuntilanakAuthor Commented:
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
ece.c: In function `insertSong':
ece.c:45: warning: assignment from incompatible pointer type
current->next_song = (Song*)insertDeleteInterface();

Open in new window

0
 
efnCommented:
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.
0
 
kuntilanakAuthor Commented:
I'll try to do that and see if it helps
0
 
kuntilanakAuthor Commented:
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

Open in new window

0
 
efnCommented:
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.
0
 
kuntilanakAuthor Commented:
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)
0
 
Infinity08Commented:
You have defined year as a char [4], while it should have been an int (just like in the struct).
0
 
kuntilanakAuthor Commented:
thanks for pointing that out
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 10
  • 6
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now