将字符串流提供给类成员函数

Posted

技术标签:

【中文标题】将字符串流提供给类成员函数【英文标题】:feeding a stringstream to a class member function 【发布时间】:2017-08-13 13:45:12 【问题描述】:

我是一个尝试边做边学的新手。我想将一个字符串流提供给一个名为“print()”的类成员函数,但我得到了错误。一旦这可行,我就可以继续编写更多类成员函数来处理我提供给它们的数据。

现在我已经创建了一个具有成员函数'print'的类。

class Month

public:
string m_month;

void print()

cout << m_month << endl;


;

接下来,我初始化了12个月:

Month month1 =  "January" ;
Month month2 =  "February" ;
Month month3 =  "March" ;
etc.

当我调用“month1.print();”时它打印一月是正确的。

我使用 stringstream 和 for 循环将月份 + 1 连接到 12,我想将 stringstream 提供给 print 函数。

stringstream os; 
string mValue = "month"; 
int iValue = 1; 

for(int i = 0; i < 12; ++i) 

    os << mValue << "" << iValue << "\n"; 
    iValue += 1; 

但是,字符串流不能与打印功能结合使用。

os.print(); and os.str().print();

导致“错误:‘std::stringstream aka class std::__cxx11::basic_stringstream’没有名为‘print’的成员”

将 stringstream 转换为 char 然后将其输入 print 函数会导致“错误:在‘cstr’中请求成员‘print’,它是非类类型‘const char*’”

const string tmp = os.str();
const char* cstr = tmp.c_str();

cstr.print();

长话短说:我要做的是将月份 + 1 连接到 12 并将其提供给类成员函数“print”。这似乎微不足道,但我无法让它发挥作用。有什么建议么?

编辑:完整代码:

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

using namespace std;

class Month

public:
string m_month;


void print()

cout << m_month << endl;


;

int main()

Month month1 =  "January" ;
Month month2 =  "February" ;
Month month3 =  "March" ;
Month month4 =  "April" ;
Month month5 =  "May" ;
Month month6 =  "June" ;
Month month7 =  "July" ;
Month month8 =  "August" ;
Month month9 =  "September" ;
Month month10 =  "October" ;
Month month11 =  "November" ;
Month month12 =  "December" ;

stringstream os; // Initialize stringstream "os"
string mValue = "month"; // Initialize mValue "month"
int iValue = 1; // Initialize iValue "1"

for(int i = 0; i < 12; ++i) 

os << mValue << "" << iValue << "\n"; // Glue mValue and iValue    
// together
iValue += 1; // Increment iValue by one


send stringstream "os" to the print function // mock code: Here I want to send month1.print(); month2.print(); etc. to the print function. The output should be January, February etc. 

return 0;

【问题讨论】:

很难理解你想用os.print();做什么。正如错误所说, print 不是字符串流的方法。您是否打算将 stringstream 字符串分配给m_month?此外,您永远不会使用月份变量。我不确定你的 iValue 循环应该做什么。请澄清。 等等,你是不是想用 mValue for-loop 来获取月份对象? 我可能在这里没有使用正确的术语,但我所做的是创建了一个包含成员“m_month”和“print”的类。我已经将第 1 个月初始化为第 12 个月,所以当我调用“month1.print();”时它打印“一月”; 'month2.print();'打印“二月”等等。现在我希望程序打印“一月、二月、三月等”,而不必输入“month1.print();到month12.print();这就是 for 循环的用途。它递增并连接我想要输入打印功能的“month1 to 12”。我将在原帖中发布完整的代码。 你的“胶水”线是否真正成为月份变量?在您当前的代码中,您从不使用 month... 变量。 【参考方案1】:

这并不像你认为的那样:

for(int i = 0; i < 12; ++i) 

    // iValue is actually unnecessary. You could have just used (i + 1)
    os << mValue << "" << iValue << "\n"; 
    iValue += 1;

所有这些都是用字符串填充字符串流:

"month1\nmonth2\nmonth3\nmonth4\nmonth5\nmonth6\nmonth7\nmonth8\nmonth9\nmonth10\nmonth11\nmonth12"

您的意图似乎是将一个数字连接到 "month" 字符串的末尾,并让它们充当您在上面定义的 month1month2... 变量。这不是它的工作原理。您不能(也不应该)尝试像那样“动态地”引用变量。在os.print(); 中,字符串流不充当Month 只是因为它包含一个与Month 变量同名的字符串。

相反,将变量添加到某种容器(如std::vector),然后循环遍历它:

std::vector<Month> months month1, month2, month3, ..., month12 

for (unsigned int i = 0; i < months.size(); i++)

    months[i].print();

【讨论】:

"您的意图似乎是将一个数字连接到“月”字符串的末尾,并让它们充当您在上面定义的第 1 个月、第 2 个月...变量..." 是,这是我的意图。感谢您建议为此使用 std::vector。我会试一试。我来自具有“自动化所有事物”心态的 Powershell 背景。动态创建变量的另一个原因是通过避免冗余来保持我的代码简洁。 @TwoGoldFish 如果您需要通过数字引用变量,请将其放入索引容器(如vector)并通过索引引用它。如果您需要通过数字以外的其他方式引用它,请将其放入 Map 并通过键查找。我不了解 PowerShell,但如果您尝试的是 PS 中的常见做法,您将需要改变您的想法。 Afaik,除非您使用调试标志进行编译,否则无论如何编译时都会丢失所有名称信息,因此这在 C++ 中甚至是不可能的。 您也可以只使用 HashMap,它可以处理所有事情,尽管它不一定能提供最佳性能。查看标准库结构。有很多选择可以处理这种情况。 当然!如果我想创建很多变量,比如说一百个,我应该使用循环创建它们并将它们存储在向量中并通过索引号引用它们。感谢您的洞察力,并感谢您的努力。真的很感激。【参考方案2】:

字符串流应该像其他任何流一样被认为是流,只是它恰好是文本并保存在内存中。所以把它转成字符串是很便宜的,实际上它们经常用于构建字符串。

但是类的“Print”方法不知道流是字符串流。它应该关心的是它得到一个文本流,并且是输入。事实上,由于历史悠久的弱点,前者有点难以执行。如果您只是逐字节读取流,传递给 std::cout,然后在 EOF 上终止,那可能没问题。

【讨论】:

以上是关于将字符串流提供给类成员函数的主要内容,如果未能解决你的问题,请参考以下文章

将标准输入中的字符串分配给类成员变量

给成员变量赋值的两种方法

使用成员函数求解方程 C++

在构造函数初始化列表中初始化 stringstream 引用成员,没有任何内容

将类的成员函数分配给 C++ 中的函数指针

构造函数-用参数初始化表对成员变量初始化