重载istream运算符>> c++

发布于 2024-11-17 04:17:22 字数 615 浏览 1 评论 0原文

假设我有一个字符向量,并且我将其作为字符串而不是字符向量推入流中,那么我如何使用运算符>>取回字符向量?

class C{
    private:
        vector<char> c;

    public:
        C(string str){
          for(int x = 0; x < str.size(); x++)
              c.push_back(str[x]);
        }

        vector<char> data(){
           return c;
        }       
};

ostream operator<<(ostream & stream, C & in){
   for(int x = 0; x < in.data().size(); x++)
      stream << in.data()[x];
   return stream;
}

istream operator>>(istream & stream, C & in){
    // ???
    // what kind of loop?
}

Say I have a vector of chars and I pushed it into a stream as a string, rather than a vector of chars, how would i get back the vector of chars using operator>>?

class C{
    private:
        vector<char> c;

    public:
        C(string str){
          for(int x = 0; x < str.size(); x++)
              c.push_back(str[x]);
        }

        vector<char> data(){
           return c;
        }       
};

ostream operator<<(ostream & stream, C & in){
   for(int x = 0; x < in.data().size(); x++)
      stream << in.data()[x];
   return stream;
}

istream operator>>(istream & stream, C & in){
    // ???
    // what kind of loop?
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

征棹 2024-11-24 04:17:22

我会像这样写你的例子......

#include <algorithm>
#include <iterator>
#include <vector>
#include <iostream>
#include <sstream>

class C
{
    std::vector<char> mData;

  public:
    // Constructor, note im using the iterator range 
    // vector constructor.
    C(const std::string& str)
    : mData(str.begin(), str.end())
    {
    }

    // Returning data by const reference to avoid 
    // copying a potentially large object.
    const std::vector<char>& data() const
    {
        return mData;
    }

    // declared the input operator as a friend as I need it to
    // access mData - alternatively you could write a "loadFromStream"
    // type function that does the same, declare this as non-friend, and call that.
    friend std::istream& operator>>(std::istream& is, C& c);
};

std::ostream& operator<<(std::ostream& os, const C& c)
{
    // Use an ostream_iterator to handle output of the vector
    // using iterators.
    std::copy(c.data().begin(), 
              c.data().end(), 
              std::ostream_iterator<char>(os, ""));

    return os;
}

std::istream& operator>>(std::istream& is, C& c)
{
    // load the data using the assign function, which
    // clears any data already in the vector, and copies 
    // in the data from the specified iterator range.
    // Here I use istream_iterators, which will read to the end
    // of the stream.  If you dont want to do this, then you could 
    // read what you want into a std::string first and assign that.
    c.mData.assign(std::istream_iterator<char>(is),
                   std::istream_iterator<char>());

    return is;
}

int main()
{
    C c("Hello");

    std::stringstream ss;
    ss << c;

    std::cout << ss.str() << std::endl;

    C d("");
    ss >> d;

    std::cout << d.data().size() << std::endl;

    return 0;
}

I'd write your example like this....

#include <algorithm>
#include <iterator>
#include <vector>
#include <iostream>
#include <sstream>

class C
{
    std::vector<char> mData;

  public:
    // Constructor, note im using the iterator range 
    // vector constructor.
    C(const std::string& str)
    : mData(str.begin(), str.end())
    {
    }

    // Returning data by const reference to avoid 
    // copying a potentially large object.
    const std::vector<char>& data() const
    {
        return mData;
    }

    // declared the input operator as a friend as I need it to
    // access mData - alternatively you could write a "loadFromStream"
    // type function that does the same, declare this as non-friend, and call that.
    friend std::istream& operator>>(std::istream& is, C& c);
};

std::ostream& operator<<(std::ostream& os, const C& c)
{
    // Use an ostream_iterator to handle output of the vector
    // using iterators.
    std::copy(c.data().begin(), 
              c.data().end(), 
              std::ostream_iterator<char>(os, ""));

    return os;
}

std::istream& operator>>(std::istream& is, C& c)
{
    // load the data using the assign function, which
    // clears any data already in the vector, and copies 
    // in the data from the specified iterator range.
    // Here I use istream_iterators, which will read to the end
    // of the stream.  If you dont want to do this, then you could 
    // read what you want into a std::string first and assign that.
    c.mData.assign(std::istream_iterator<char>(is),
                   std::istream_iterator<char>());

    return is;
}

int main()
{
    C c("Hello");

    std::stringstream ss;
    ss << c;

    std::cout << ss.str() << std::endl;

    C d("");
    ss >> d;

    std::cout << d.data().size() << std::endl;

    return 0;
}
琉璃梦幻 2024-11-24 04:17:22

您始终可以从另一个构造一个:

std::vector<char> A = getVector();
std::string       B = getString();

std::vector<char> newB(B.begin(), B.end());
std::string       newA(A.begin(), A.end());

使用它您应该能够编写您的流内运算符,例如

std::string stmp;
stream >> stmp;
std::vector<char> vtmp(stmp.begin(), stmp.end());
c.swap(vtmp);

You can always construct one from the other:

std::vector<char> A = getVector();
std::string       B = getString();

std::vector<char> newB(B.begin(), B.end());
std::string       newA(A.begin(), A.end());

Using that you should be able to write your in-stream operator, e.g.

std::string stmp;
stream >> stmp;
std::vector<char> vtmp(stmp.begin(), stmp.end());
c.swap(vtmp);
戒ㄋ 2024-11-24 04:17:22

做什么>>对于 std::string 确实如此,您实际上只需要使用 std::string 即可。请注意,您需要通过引用而不是值传递C,并且运算符应通过引用返回原始流。另外,我忍不住认为使用 std::vector 而不是 std::string 并不是那么有用(另外,ctor 效率低下) — 如果你这样做的话,至少保留 str.length())。

istream& operator>>(istream& s, C& in) {
    std::string tmp;
    s >> tmp;
    // you also need to return reference in in.data() for this to work
    // or declare operator>> as friend and use in.c directly
    in.data().assign(tmp.begin(), tmp.end());
    return s;
}

To do what >> for std::string does, well, you really just need to use std::string. Note that you need to pass C by reference, not by value, and operators should return the original stream by reference. Also, I can't help but think that using std::vector<char> instead of std::string is not really that useful (plus, the ctor is inefficient — at least reserve str.length() if you're doing this).

istream& operator>>(istream& s, C& in) {
    std::string tmp;
    s >> tmp;
    // you also need to return reference in in.data() for this to work
    // or declare operator>> as friend and use in.c directly
    in.data().assign(tmp.begin(), tmp.end());
    return s;
}
沧笙踏歌 2024-11-24 04:17:22

您可以使用 istream 迭代器。
其默认构造函数初始化为流末尾。

http://www.cplusplus.com/reference/std/iterator/istream_iterator/

你的代码看起来像这样。

typedef std::istream_iterator<char> charstream_it;
c = std::vector<char>(charstream_it(stream),  charstream_it());

在构造函数中,您可能应该按照 Kerrek SB 的建议使用 STL 迭代器样式的复制构造函数。

C::C(string str):
c(str.begin(), str.end()) {};

You can use the istream iterator.
Its default constructor initializes to end of stream.

http://www.cplusplus.com/reference/std/iterator/istream_iterator/

Your code would then look something like.

typedef std::istream_iterator<char> charstream_it;
c = std::vector<char>(charstream_it(stream),  charstream_it());

In your constructor, you should probably use the STL iterator style copy constructor as advised by Kerrek SB.

C::C(string str):
c(str.begin(), str.end()) {};
眼波传意 2024-11-24 04:17:22

首先,您需要将流作为引用而不是按值返回。另外,data() 应该返回对向量的 const 引用,以便它不会被复制(如果它是一个大向量,这一点很重要)。

至于重载>>,我会尝试类似的方法:

istream& operator>>(istream& stream, C& in) {
    for (char c; /* some end condition */;) {
        stream >> c;
        in.c.push_back(c);
    }
}

当然,这种方法需要声明operator>>(istream&, C&) 一个友元函数。另一种方法是向公共接口提供相当于 append(char) 函数的功能。另外,data() 应标记为 const,因此整个签名将是 const vector& data() const 明确表明它是严格的访问器。

First of all, you'll want to return your streams as references instead of by value. Also, data() should return a const reference to the vector, so that it isn't copied (important if it's a large vector).

As for overloading >>, I would try something like:

istream& operator>>(istream& stream, C& in) {
    for (char c; /* some end condition */;) {
        stream >> c;
        in.c.push_back(c);
    }
}

Of course, this approach would require declaring operator>>(istream&, C&) a friend function. The alternative is to supply the equivalent of an append(char) function to your public interface. Also, data() should be marked const, so the whole signature would be const vector<char>& data() const making it clear that it is strictly an accessor.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文