Передача строкового потока как ostream &, содержимое не читается

Я кодирую задание, в котором, по сути, у меня есть связь между клиентом и сервером. Для этого я использую строковый поток на стороне сервера для обработки запросов (которые поступают в форме строк) и помощи в построении строкового ответа. На стороне сервера находится объект (FileManager), который содержит несколько объектов MultimediaFile, каждый из которых содержит информацию о себе. Эта информация может быть напечатана с помощью метода, одним из параметров которого является ostream &.

Чтобы получить запрос от клиента, поток строк работает нормально, но когда я передаю его методу, он по какой-то причине не читает содержимое (тогда как если я передаю std :: cout, он работает нормально). Я думаю, это как-то связано с тем, как stringstream использует оператор ‹< для чтения информации, но я не знаю, как это исправить.

Я знаю, что могу просто сохранить нужную мне информацию об объекте в строке или что-то в этом роде (вместо использования ostream &), но профессор хочет, чтобы метод печатал непосредственно в переданный ostream, а не возвращал строку.

Вот код:

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 - это класс, предоставленный профессором для упрощения работы, но в основном клиент отправляет строку request и в конце этой функции получает строку ответ от сервера. filem - это объект класса FileManager, а вот код метода showFile:

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

mfiles - это отображение строки в MultimediaFile * (в частности, std :: shared_ptr из MultimediaFile, но в любом случае). По сути, этот код проверяет, существует ли файл с именем name, и если да, вызывает метод printFile (s), где s здесь будет струнный поток. Вот код метода:

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

name и filepath - это переменные экземпляра класса MultimediaFile. Итак, да, здесь я ожидал, что мой поток строк получит эту информацию, которая затем будет использована для построения строки response в основной части кода сразу после вызова метода. Однако это не то, что происходит, и строковый поток всегда пуст (и поскольку это работает с std :: cout, проблема не в данных в объекте MultimediaFile).

Опять же, я бы сказал, что stringstream ведет себя иначе, чем cout при получении данных с помощью оператора ‹<, но я не смог найти никакой информации, которая могла бы мне помочь в этом случае ... У кого-нибудь есть идея?

Если вам нужна другая информация, пожалуйста, дайте мне знать. И заранее спасибо!


person Berne    schedule 17.02.2016    source источник
comment
Просто в качестве примечания: почему вы используете operation.compare("print") == 0 вместо operation == "print"?   -  person Nobody moving away from SE    schedule 17.02.2016
comment
Не думаю, что он должен вести себя иначе и не может воспроизвести такую ​​проблему. Вы уверены, что пути кода совпадают? if в showFile решает по-разному между cout и stringstream вариантом?   -  person Nobody moving away from SE    schedule 17.02.2016
comment
Да, пути такие же. Я пробовал использовать gdb, и он сразу переходит к этому фрагменту кода, так что он должен быть таким же, верно?   -  person Berne    schedule 17.02.2016
comment
Кроме того, для сравнения, признаюсь, я не помню почему, ха-ха. Я думаю, что получал какое-то предупреждение при использовании ==. Я бы попробовал еще раз, чтобы проверить, но, к сожалению, я нахожусь в классе, поэтому мне придется дать вам лучший ответ позже.   -  person Berne    schedule 17.02.2016
comment
and it goes straight to that bit of code Какой бит? Вы должны попытаться предоставить код, воспроизводящий проблему. Учитывая текущую информацию, я (и, вероятно, другие тоже) не могу ее воссоздать.   -  person Nobody moving away from SE    schedule 17.02.2016
comment
Я имел в виду, что и cout, и stringstream вызывают один и тот же метод, они выполняют одни и те же строки. Но я предоставлю что-то воспроизводимое как можно скорее, спасибо!   -  person Berne    schedule 17.02.2016
comment
Нашел решение (которое порождает новые вопросы, но в любом случае просто сделал новый пост с ответом). Кроме того, я действительно не помню, почему я использовал сравнение, поэтому я просто изменил его обратно, ха-ха. И извините за задержку, занялся другим делом.   -  person Berne    schedule 20.02.2016


Ответы (1)


Итак, видимо, я нашел решение.

Чтобы проверить некоторые вещи, я попытался создать отдельный фрагмент кода, просто чтобы проверить, как метод будет вести себя со строковым потоком. И ... это сработало. Единственная разница между моими отдельными тестами и самой проблемой заключалась в том, что в моей программе поток строк использовался для получения данных из строки request перед передачей методу для получения данных оттуда. Итак, что я сделал, я создал второй поток строк, который был передан методу ... и он сработал.

По сути, это то, что я изменил (остальной код такой же, как и в исходном посте):

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

Понятия не имею, почему не работает первый поток строк; возможно, один из методов, которые я использовал для получения информации request (str (), get (), getline () или оператор >>) изменить состояние строкового потока так, чтобы он не принимал новую информацию? Не знаю, просто случайные мысли.

Но в любом случае это работает, так что пока я счастлив ...

P.S .: Я тоже поменял operation.compare("print") на operation == "print". Я не мог вспомнить причину, по которой я использовал compare, и я не получал предупреждений во время компиляции, как я думал, так что да ...

person Berne    schedule 20.02.2016
comment
Вероятно, проблема та же, что описана в этом вопросе. - person Nobody moving away from SE; 22.02.2016