2

I am shuffling songs for my program but im a little confused because when I try the compiler tells me I cant compare my struct to an int. Im wondering what yall might think?

struct Songs                 //my struct
{
string title;     
string artist;
string mem;  
};

Songs *ptr;
ptr = new Songs[25];    //dynamic array

so i told u the struct and ptr well heres the function im experiencing trouble..

void shuffle (Songs song[], Songs *ptr, string title, string mem, string  artist, int num)
{

 for (int i=0; i<(num); i++) 
 {
     int r = i + (rand() % (num-i)); // Random remaining position.
     int temp = ptr[i]; ptr[i] = ptr[r]; ptr[r] = temp;  //this isnt working
 }                                                     //but its logically sound?   

 for (int c=0; c<n; c++) 
 {
     cout << ptr[c] << " ";  // Just print 
 }      
}
gamergirl22
  • 149
  • 1
  • 4
  • 16

5 Answers5

3

The offending code is at int temp = ptr[i]; ... ptr[r] = temp;, you're assigning Song and int which is not possible.

Additionally, I strongly suggest using std::vector< Song > for storage. Your code is more robust and will crash less likely, plus the vector always knows the number of Songs it contains. Example

#include <vector>
...
struct Song { ... };
...
void shuffle(std::vector< Song >& mySongs, ...)
{
   /* shuffle mySongs somehow. */
   ...
}

mySongs.size() contains the number of songs, and you can access each song with mySongs[index] (or better mySongs.at(index)) as expected. Adding new songs is done by mySongs.push_back(someSong).

Now to your question: How do I shuffle my vector of songs. Well ...

/* at start of program. */
srand(unsigned(time(NULL)));
...
void shuffle(std::vector< Song >& mySongs)
{
    std::random_shuffle(mySongs.begin(), mySongs.end());
}

does the trick. See here.

Writing a song to a stream can be done by defining a function like this:

std::ostream& operator << (std::ostream& osr, const Song& mySong)
{
    osr << mySong.title << ' ' << mySong.artitst << ' ' << mySong.mem;
    return osr;
}

Now you can happily do std::cout << mySong << std::endl.

Community
  • 1
  • 1
hochl
  • 12,524
  • 10
  • 53
  • 87
  • thnx for this help ..it now shuffles great but vectors are new to me. do i cout them as i would regular arrays? for example: for (int i=0; i – gamergirl22 Feb 29 '12 at 10:01
  • Should work as expected. Even better, you can give your Song object a function that writes it to a stream. I'll add to my answer in a few. – hochl Feb 29 '12 at 10:07
  • thnx again. idk why we arent taught vectors but they seem so much simpler. i am gonna study these on my own now because they seem incredibly useful. – gamergirl22 Feb 29 '12 at 10:11
  • Possibly the goal of your course is to learn how to use pointers, in this case they might object if you use a `vector` instead. But for practical purposes `vector` is the way to go. – hochl Feb 29 '12 at 10:18
2

You should really try to use more out of the standard library. With std::vector and std::random_shuffle this would be so much cleaner. Edit: Code now with output.

#include <iostream>
#include <ostream>
#include <algorithm>
#include <string>
#include <vector>

struct song
{
    std::string title;     
    std::string artist;
    std::string mem;  
};

std::ostream& operator << (std::ostream& stream, const song& s)
{
    return stream << "Song: { Title: " << s.title 
        << ", Artist: " << s.artist << ", Mem: " << s.mem;
}

template <typename T>
std::ostream& operator << (std::ostream& stream, const std::vector<T>& v)
{
    stream << '[';
    for (auto i = v.begin(); i != v.end(); ++i)
        stream << *i << ", \n";
    return stream << ']';
}
int main()
{
    std::vector<song> songs;
    // .push_back your songs
    std::random_shuffle(songs.begin(), songs.end());
    std::cout << songs;
}
cooky451
  • 3,460
  • 1
  • 21
  • 39
  • wow interesting ..we've not gotten to vectors but this seems so simple. do i pass vector to the function as well? thnx again – gamergirl22 Feb 29 '12 at 09:50
  • Well, the vector is basicly your dynamic array, but you don't need to bother with manual resizing/freeing etc. - random_shuffle is a template function, you pass in iterators, begin points to the first and end after the last element. – cooky451 Feb 29 '12 at 09:53
  • thank u cooky. would u suggest i cout<< vector to write the shuffle? – gamergirl22 Feb 29 '12 at 10:03
  • I edited the code. It shows the idea, you can of course change the formatting as you wish. – cooky451 Feb 29 '12 at 10:17
1

You are trying to assign a Songs object to an int (int temp = ptr[i];), and then you try to assign an int to a Songs (ptr[r] = temp;). That will not work. To make it work, I suggest you change the line to: Songs temp = ptr[i]; ptr[i] = ptr[r]; ptr[r] = temp;

Zyx 2000
  • 1,625
  • 1
  • 12
  • 18
1

Change:

int temp = ptr[i]; ptr[i] = ptr[r]; ptr[r] = temp;

to

Songs temp = ptr[i]; ptr[i] = ptr[r]; ptr[r] = temp;

Your original code tries to assign a Songs to an integer. You need to create a temporary of the same type as the object you are trying to assign it.

Dervall
  • 5,736
  • 3
  • 25
  • 48
1

Well, why are you using an int to store the struct value? Just make it:

Songs temp;

Also, your type names are totally confusing, Songs seems to represent a single song.

unwind
  • 391,730
  • 64
  • 469
  • 606