У меня возникли проблемы с std :: cout, std :: stringstream и std :: string.c_str(). В основном, кажется, что есть вещи, которые где-то попадают в буфер, и я не уверен, как исправить эту проблему.StringStream/c_str() коррупция в C++
Если вы не любите читать код в StackOverflow, вот соответствующие ссылки на мой GitHub: TLString class, то Test class и the unit test - и вы можете пропустить до конца, где я сформулируем мой более краткий вопрос.
В моем модульном тестировании, у меня есть следующий код:
Test <std::string> strtest; // A unit test object expecting strings.
Test <const char*> chtest; // A unit test object expecting const char*s
// ...
TurnLeft::Utils::TLString str3("Exterminate.");
// ...
/* Basically, name() and expect() will use the passed arg.
* in the output in order to
* display output such as the following:
* str(): expecting 'Exterminate.' | Actual 'Exterminate.' => PASS
*/
strtest.name("str()").expect("Exterminate.").test(str3.str());
/* To try and determine where the corruption was occuring, I did a
* simple cout here, and got what should be the expected result of
* the next test,
* meaning that the actual test should be succeeding.
*/
std::cout << str3.c_str() << std::endl //outputs Exterminate. normally.
/* But when I try to invoke that same method (c_str()) within the test
* object, it simply copies the argument passed in for name().
*/
chtest.name("c_str()").expect("Exterminate.").test(str3.c_str());
// Should output 'Exterminate.' as in the saatement before, but instead
// outputs 'c_str()'.
Вот код класса Test:
namespace unittest{
static std::string status[2] = {"FAIL", "PASS"};
template <class ExpectedResult>
class Test
{
private:
ExpectedResult expected;
ExpectedResult actual;
std::string testName;
public:
Test();
Test <ExpectedResult>& expect (ExpectedResult value);
Test <ExpectedResult>& name (std::string);
void test (ExpectedResult value);
};
template <class ExpectedResult> Test <ExpectedResult>&
Test<ExpectedResult>::expect(ExpectedResult value)
{
expected = value;
return *this;
}
template <class ExpectedResult>
Test <ExpectedResult>&
Test<ExpectedResult>::name(std::string aName)
{
testName = aName;
return *this;
}
template <class ExpectedResult>
void Test<ExpectedResult>::test(ExpectedResult value)
{
actual = value;
std::cout << testName << ": ";
std::cout << "Expecting: " << expected << " | ";
std::cout << "Actual: " << actual;
std::cout << " => " << status[actual==expected] << std::endl;
}
Класс TLString это один, что я пишу, что даст еще несколько операций с жидкостями для строк в C++ (например, конкатенация). Он использует строковый поток для обработки этих операций. Метод TLStream::c_str()
действительно просто делает это: return stream.str().c_str();
Таким образом, я действительно путают о том, как actual
в настоящее время присваивается значение testName
. Я не уверен, где происходит конфликт, учитывая, что единственное время, когда те, к переменным, приближаются к взаимодействию, - это когда они выводятся в CLI и даже более похожи, поскольку в этом случае эти два являются разными типами данных.
Я написал в функции c_str(), потому что вы просто не знаете, когда какая-то сторонняя библиотека будет полагаться на строки C вместо строк C++ и не видит причин ограничивать мой класс. Даже в std :: ios вам нужно использовать строки c для некоторых вещей.
Любая помощь была бы принята с благодарностью.
Спасибо!
Просто интересно, что не так с использованием 'append' или' operator +/operator + = 'для конкатенации? – chris
Я реализую оператор + и оператор + = в классе, который я пишу; Я не счел целесообразным перегрузить оператора стандартным библиотечным объектом. Есть и другие функции, которые я добавляю. Однако я не знал о добавлении. Итак, это супер полезно. –
Бах, я думал, что у ветки есть все исправления. Я также заметил, пытаясь решить этот пролив, что я возвращаю копию объекта, а не ссылку на тот же объект. Фактическое определение читает Test & name (std :: string); Я, должно быть, не добавил и не совершил эти изменения. Мои извинения. –