0

I am trying to swap strings. For one of my functions of my class, I am passing in two strings and I also created a temp variable. I have been trying to compile my code, but it says "no suitable function for conversion from std::string to const char* exists.

void CdLib::swap(string *s1, string *s2)
{
    string temp;

    strcpy(temp, *s1);
    strcpy(*s1, *s2);
    strcpy(*s1, temp);
}
class CdLib
{
public:

    int n;
    char Cd[N_MAX];

    string artist;
    string title;
    int year;
    string genre;
    string fan;
    string imageURL;

    CdLib();
    void setFromFile(string fileName);
    void print(string label);
    void sortByYear();
    void sortByArtist();
    void sortByTitle(string genres[]);

private:
    void swap(int *a, int *b);
    void swapStrings(string *s1, string *s2);
};

I'm confused why it is trying to convert between string and char when they should all be string. Thank you.

3 Answers3

2

strcpy() takes char* pointers, not string* pointers. It you are not allocating any memory for strcpy() to copy into.

Rather than using strcpy() at all, a better solution is to use std::string::operator= instead:

void CdLib::swap(string *s1, string *s2)
{
    string temp = *s1;
    *s1 = *s2;
    *s1 = temp;
}

Or better, std::swap():

void CdLib::swap(string *s1, string *s2)
{
    std::swap(*s1, *s2);
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
1

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.

  1. std::swap supports pretty much everything, so use that.

  2. 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).

  3. 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.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
0
#include <iostream>
#include<bits/stdc++.h>
using namespace std;

int main() {
    string str1 = "Hello";
    string str2 = "World";
    swap(str1,str2);
    cout<<str1<<" ";
    cout<<str2;
}

o/p: Success #stdin #stdout 0s 4492KB World Hello