如何强制 std::stringstream 运算符 >> 读取整个字符串?

发布于 2024-07-26 17:15:18 字数 527 浏览 13 评论 0原文

如何强制 std::stringstream 运算符 >> 读取整个字符串而不是停在第一个空格处?

我有一个模板类,它存储从文本文件读取的值:

template <typename T>
class ValueContainer
{
protected:
  T m_value;

public:
  /* ... */
  virtual void fromString(std::string & str)
  {
    std::stringstream ss;
    ss << str;
    ss >> m_value;
  }
  /* ... */
};

我尝试设置/取消设置流标志,但没有帮助。

说明

该类是一个容器模板,可以自动与 T 类型相互转换。字符串只是该模板的一个实例,它还必须支持其他类型。 这就是为什么我想强制运算符>> 模仿 std::getline 的行为。

How to force std::stringstream operator >> to read an entire string instead of stopping at the first whitespace?

I've got a template class that stores a value read from a text file:

template <typename T>
class ValueContainer
{
protected:
  T m_value;

public:
  /* ... */
  virtual void fromString(std::string & str)
  {
    std::stringstream ss;
    ss << str;
    ss >> m_value;
  }
  /* ... */
};

I've tried setting/unsetting stream flags but it didn't help.

Clarification

The class is a container template with automatic conversion to/from type T. Strings are only one instance of the template, it must also support other types as well. That is why I want to force operator >> to mimic the behavior of std::getline.

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

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

发布评论

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

评论(6

第七度阳光i 2024-08-02 17:15:19

如果您可以使用 Boost 则使用 boost::lexical_cast

If you can use Boost then use boost::lexical_cast.

风吹雪碎 2024-08-02 17:15:18

作为运算符>> 当 T=string 时不满足我们的要求,我们可以针对 [T=string] 情况编写特定的函数。 这可能不是正确的解决方案。 但是,正如解决方法所提到的。

如果不能满足您的要求,请纠正我。

我写了一个示例代码如下:

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

template <class T>
class Data
{
    T m_value;
    public:
    void set(const T& val);
    T& get();
};

template <class T>
void Data<T>::set(const T& val)
{
    stringstream ss;
    ss << val;
    ss >> m_value;
}

void Data<string>::set(const string& val)
{
    m_value = val;
}

template <class T>
T& Data<T>::get()
{
    return m_value;
}

int main()
{
    Data<int> d;
    d.set(10);
    cout << d.get() << endl;

    Data<float> f;
    f.set(10.33);
    cout << f.get() << endl;

    Data<string> s;
    s.set(string("This is problem"));
    cout << s.get() << endl;
}

As operator >> is not satisfying our requirement when T=string, we can write a specific function for [T=string] case. This may not be the correct solution. But, as a work around have mentioned.

Please correct me if it won't satisfy your requirement.

I have written a sample code as below:

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

template <class T>
class Data
{
    T m_value;
    public:
    void set(const T& val);
    T& get();
};

template <class T>
void Data<T>::set(const T& val)
{
    stringstream ss;
    ss << val;
    ss >> m_value;
}

void Data<string>::set(const string& val)
{
    m_value = val;
}

template <class T>
T& Data<T>::get()
{
    return m_value;
}

int main()
{
    Data<int> d;
    d.set(10);
    cout << d.get() << endl;

    Data<float> f;
    f.set(10.33);
    cout << f.get() << endl;

    Data<string> s;
    s.set(string("This is problem"));
    cout << s.get() << endl;
}
嘿咻 2024-08-02 17:15:18

这是一个解决方案:(

std::istream & ReadIntoString (std::istream & istr, std::string & str) 
{ 
    std::istreambuf_iterator<char> it(istr), end; 
    std::copy(it, end, std::inserter(str, str.begin())); 
    return istr; 
} 

感谢 C++ 新闻组中的原始发布者)

Here is a solution :

std::istream & ReadIntoString (std::istream & istr, std::string & str) 
{ 
    std::istreambuf_iterator<char> it(istr), end; 
    std::copy(it, end, std::inserter(str, str.begin())); 
    return istr; 
} 

(Thanks to the original poster in C++ newsgroup)

墨落画卷 2024-08-02 17:15:18

你想让它停在哪里? 如果你想阅读整行,你可能需要 getline 函数,如果你需要一个您选择的存储在streamstring对象中的整个字符串是 ostringstream::str 方法。

Where do you want it to stop? If you want to read a whole line you probably need getline function, if you need an entire string stored in the streamstring object your choise is ostringstream::str method.

云朵有点甜 2024-08-02 17:15:18

我假设您正在使用 T = std::string 实例化该模板。 在这种情况下,您可以使用 getline:

getline(ss, m_value, '\0');

但是,这假设您不接受空字符作为字符串的有效部分。

否则,您可以为“T”编写自己的提取器。

I'm assuming you're instantiating that template with T = std::string. In that case you could use getline:

getline(ss, m_value, '\0');

However, this assumes you won't accept nul-characters as valid parts of the string.

Otherwise you can write your own extractor for `T'.

白况 2024-08-02 17:15:18

没有办法使用运算符>> 我知道除了编写自己的方面(operator>> 在 isspace(c, getloc()) 为 true 的第一个字符处停止)。 但是中有一个getline函数 其中有你想要的行为。

There isn't a way with operator>> that I'm aware of excepted writing your own facet (operator>> stop at first character for which isspace(c, getloc()) is true). But there is a getline function in <string> which has the behaviour you want.

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