将 stringstream 作为 ostream& 传递,没有内容被读取

Passing stringstream as ostream&, no content being read

我正在编写一项作业,基本上,我有一个客户端和服务器进行通信。为此,我在服务器端使用字符串流来处理请求(以字符串形式出现)并帮助构建字符串响应。服务器端持有一个包含多个 MultimediaFile 对象的对象 (FileManager),每个对象都有关于它们自己的信息。这个信息可以通过一个方法打印出来,其中一个参数是ostream&。

为了从客户端获取请求,stringstream 工作得很好,但是当我将它传递给方法时,由于某种原因它不读取内容(而如果我传递 std::cout 它工作正好)。我认为这与 stringstream 使用 << 运算符读取信息的方式有关,但我不确定如何更正此问题。

我知道我可以简单地将我需要的关于对象的信息存储在字符串或类似的东西中(而不是使用 ostream&),但是教授希望该方法直接打印到传递的 ostream,而不是 return一个字符串。

代码如下:

bool processRequest(TCPServer::Cnx& cnx, const string& request, string& response)
{
bool changeData = false;
if (request == "delMedias" || request == "delGroups") changeData = true;

TCPServer::Lock lock(cnx, changeData);

cerr << "request: '" << request << "'" << endl;
string operation = "";
string filename = "";
stringstream iss;

iss.str(request); //next few lines get request info, works just fine!

if (iss.rdbuf()->in_avail() != 0)
    iss >> operation;
if (iss.rdbuf()->in_avail() != 0)
    iss.get();
if (iss.rdbuf()->in_avail() != 0)
    getline(iss, filename);
iss.str("");


if (operation.size() == 0 || filename.size() == 0) return false;

response = "";

if (operation.compare("print") == 0)
{
        filem.showFile(filename, iss); //Problem here!!!!
        if (iss.rdbuf()->in_avail() != 0) //iss is always empty
        {
            response = iss.str();
            response = "Print info: " + response;
        }
        else
            response = "No info received!";
}
else if (operation.compare("play") == 0)
{
        filem.playFile(filename);
        response = "File played!";
}
else
    response = "Operation not valid";

cerr << response << endl;

return true;
}

TCPServer是教授提供的一个class为了方便,但是基本上客户端发送一个字符串request并且,在此函数的末尾,从服务器接收到一个字符串 responsefilem 是 FileManager class 对象,下面是 showFile 方法的代码:

void FileManager::showFile(string name, ostream& s)
{
    if (mfiles.find(name) != mfiles.end())
        mfiles[name]->printFile(s);
}

mfiles 是字符串到 MultimediaFile* 的映射(特别是 MultimediaFile 的 std::shared_ptr,但无论如何)。基本上,此代码检查是否存在名为 name 的文件,如果存在,则调用方法 printFile(s) where s 这里是字符串流。这是该方法的代码:

void MultimediaFile::printFile(ostream& s) const
{
    s << "File name: " << name << "\tFilepath: " << filepath << "\n";
}

namefilepath 是 MultimediaFile class 的实例变量。所以,是的,在这里我期待我的 stringstream 接收此信息,然后将在方法调用之后用于在代码的主要部分构建 response 字符串。然而,情况并非如此,字符串流始终为空(并且由于这适用于 std::cout,因此问题不在于 MultimediaFile 对象中的数据)。

同样,当通过 << 运算符获取数据时,我会说 stringstream 的行为与 cout 不同,但在这种情况下我找不到任何对我有帮助的信息...有人知道吗?

如果您需要任何其他信息,请告诉我。提前致谢!

所以,显然我找到了解决方案。

为了测试一些东西,我尝试创建一段单独的代码来检查该方法如何处理字符串流。而且……它奏效了。我的单独测试和问题本身之间的唯一区别是,在我的程序中,stringstream 在传递给获取数据的方法之前被用于从 request 字符串中获取数据从那里。所以,我所做的是,我创建了第二个 stringstream 并传递给该方法...并且它起作用了。

基本上我改的就是这个(其余代码和原来的一样post):

response = "";
stringstream iss2; //create another stringstream

if (operation == "print")
{
        filem.showFile(filename, iss2); //use it instead of the first one
        if (iss2.rdbuf()->in_avail() != 0)
        {
            response = iss2.str();
            response = "Print info: " + response;
        }
        else
            response = "No info received!";
}

我不知道为什么第一个 stringstream 不起作用;也许是我用来获取 request 信息的方法之一 (str(), get() , getline()>> 运算符)更改字符串流的状态以使其不接受新信息?我不知道,只是随意的想法。

但无论如何,这有效,所以我现在很高兴...

P.S.: 我也把operation.compare("print")改成了operation == "print"。我不记得我使用 compare 的原因,并且在编译过程中没有像我想的那样收到警告,所以,是的...