【问题标题】:How to swap strings?如何交换字符串?
【发布时间】:2020-12-06 23:04:41
【问题描述】:

我正在尝试交换字符串。对于我班级的一个函数,我传入了两个字符串,并且还创建了一个临时变量。我一直在尝试编译我的代码,但它说“不存在从 std::string 转换为 const char* 的合适函数。

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);
};

我很困惑为什么当它们都应该是字符串时它试图在字符串和字符之间进行转换。谢谢。

【问题讨论】:

  • 为什么要传递指向字符串的指针?你知道什么是参考文献吗?此外,除非您尝试自己编写,否则有一个 std::swap
  • 你不想要 strcpy,你想要 operator=() 或 std::swap
  • 我猜你的代码中的string指的是std::string?在这种情况下,您使用= 复制它们,而不是strcpy
  • strcpy 适用于 char* 而不是 std::string。您将 C 方式与 C++ 方式混淆了。
  • 不要重新发明轮子。阅读std::swap

标签: c++


【解决方案1】:

strcpy() 采用 char* 指针,而不是 string* 指针。如果您没有分配任何内存供 strcpy() 复制到。

完全不用strcpy(),更好的解决方案是改用std::string::operator=

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

或者更好,std::swap():

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

【讨论】:

    【解决方案2】:

    我正在尝试交换字符串

    为什么需要?排序可以通过std::sort 完成,您不必担心字符串如何交换——这就是 C++ 的美妙之处,这些基本操作都在标准库中实现。

    1. std::swap 支持几乎所有东西,所以使用它。

    2. 不要通过值将字符串作为参数传递。通过 const 引用传递它们。按值返回它们。如果一个函数打算修改一个字符串,那么它应该通过非常量引用(即“只是”一个引用)来获取它。

    3. 不要写using namespace std - 这是不好的做法。

    我猜CdLib 类是某种 CD 库,但您还没有告诉我们您的程序还应该做什么。

    如果我要为此写一个草图,我会从表示 CD 信息的结构、可用于分类的 CD 比较函数、打印 CD 信息的函数以及将 CD 信息流式传输到/从 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;
    }
    

    然后我会编写一个代表 CD 库的类,其中包含访问单个 CD 的方法、访问整个集合的迭代器、使用 std::sort 算法的方法和对库进行排序的比较函数以及加载方法/save it from/to file,并打印整个库(默认为标准输出):

    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);
            }
        }
    };
    

    当然,我也会为整个库实现流式操作符,就像我们为单个 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;
    }
    

    那么,loadsave 便利方法可以用这些流操作符的 n 项表示:

    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;
    }
    

    希望这能让您对此类代码的外观有所了解。我不太确定你希望用void sortByTitle(string genres[]) 实现什么,所以我没有实现它。随时在此答案下发表评论以进行解释,并编辑问题以明确您需要什么功能。

    【讨论】:

      【解决方案3】:
      #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: 成功 #stdin #stdout 0s 4492KB 世界你好

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-19
        • 1970-01-01
        • 2014-06-28
        • 2021-10-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多