I am trying to swap strings
Why would you need to? Sorting can be accomplished via std::sort
and you don't have to worry about how the strings get swapped - that's the beauty of C++, such basic operations are all implemented in the standard library.
std::swap
supports pretty much everything, so use that.
Don't pass strings as arguments by value. Pass them by const reference. Return them by value. If a function is intended to modify a string in place, then it should take it by non-const reference (i.e. "just" a reference).
Don't write using namespace std
- it's bad practice.
I guess that the CdLib
class is some sort of a CD library, but you haven't told us what else your program should do.
If I were to write a sketch of this, I'd start with a structure representing the CD information, comparison functions for the CD that can be used in sorting, a function to print out the CD information, and a way to stream the CD information to/from an ostream/istream:
#include <algorithm>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
struct CDInfo
{
std::string artist;
std::string title;
std::string genre;
std::string fan;
std::string imageUrl;
int year;
friend void swap(CDInfo& a, CDInfo& b)
{
// see https://stackoverflow.com/a/2684544/1329652 for rationale
using std::swap; // bring in swap for built-in types
swap(a.artist, b.artist);
swap(a.title, b.title);
swap(a.genre, b.genre);
swap(a.fan, b.fan);
swap(a.imageUrl, b.imageUrl);
swap(a.year, b.year);
}
};
bool lessByYear(const CDInfo &l, const CDInfo &r) {
return l.year < r.year;
}
bool lessByArtist(const CDInfo &l, const CDInfo &r) {
return l.artist < r.artist;
}
void print(std::ostream &os, const CDInfo &cd) {
os << "Artist: " << cd.artist
<< "\n Title: " << cd.title
<< "\n Genre: " << cd.genre
<< "\n Fan: " << cd.fan
<< "\n Image: " << cd.imageUrl
<< "\n Year: " << cd.year << "\n";
}
std::istream &operator>>(std::istream &is, CDInfo &cd)
{
std::string year;
std::getline(is, cd.artist);
std::getline(is, cd.title);
std::getline(is, cd.genre);
std::getline(is, cd.fan);
std::getline(is, cd.imageUrl);
if (std::getline(is, year)) cd.year = std::stoi(year);
return is;
}
std::ostream &operator<<(std::ostream &os, const CDInfo &cd)
{
os << cd.artist << '\n' << cd.title << '\n'
<< cd.genre << '\n' << cd.fan << '\n'
<< cd.imageUrl << '\n' << cd.year << '\n';
return os;
}
Then I'd write a class representing the CD library, with methods to access the individual CDs, iterators to access the entire collection, methods using the std::sort
algorithm and the comparison functions to sort the library, and methods to load/save it from/to file, and to print the entire library (by default to stdout):
class CDLibrary
{
std::vector<CDInfo> m_CDs;
public:
CDLibrary() = default;
int count() const { return m_CDs.size(); }
void resize(int newCount) { m_CDs.resize(newCount); }
CDInfo &getCD(int index) { return m_CDs[index]; }
const CDInfo &getCD(int index) const { return m_CDs[index]; }
auto begin() { return m_CDs.begin(); }
auto end() { return m_CDs.end(); }
auto begin() const { return m_CDs.begin(); }
auto end() const { return m_CDs.end(); }
auto cbegin() const { return m_CDs.begin(); }
auto cend() const { return m_CDs.end(); }
void sortByYear() {
std::sort(begin(), end(), lessByYear);
}
void sortByArtist() {
std::sort(begin(), end(), lessByArtist);
}
void addCD(const CDInfo &cd) {
m_CDs.push_back(cd);
}
void removeCD(int index) {
m_CDs.erase(m_CDs.begin() + index);
}
bool load(const std::string &filename);
bool save(const std::string &filename) const;
void printAll(std::ostream &os = std::cout) const {
int n = 1;
for (auto &cd : *this) {
os << "--- CD #" << n << '\n';
print(os, cd);
}
}
};
Of course I'd also implement the streaming operators for the entire library, just as we did for the individual CDInfo:
std::istream &operator>>(std::istream &is, CDLibrary &lib) {
std::string count;
if (std::getline(is, count)) {
lib.resize(std::stoi(count));
for (auto &cd : lib)
if (!(is >> cd)) break;
}
return is;
}
std::ostream &operator<<(std::ostream &os, const CDLibrary &lib) {
if (!(os << lib.count() << '\n')) return os;
for (auto &cd : lib)
if (!(os << cd)) break;
return os;
}
Then, the load
and save
convenience methods can be expressed n terms of those streaming operators:
bool CDLibrary::load(const std::string &filename) {
std::ifstream ifs(filename);
try {
return ifs.good() && ifs >> *this;
} catch (...) {}
return false;
}
bool CDLibrary::save(const std::string &filename) const {
std::ofstream ofs(filename);
return ofs.good() && ofs << *this;
}
Hopefully this gives you some idea how such code might look. I'm not quite sure what you expected to achieve with void sortByTitle(string genres[])
, so I didn't implement it. Feel free to comment under this answer to explain, as well as edit the question to make it clear what is the functionality you need.