У меня есть переменная ostringstream, которая содержит некоторые данные.
Я хочу установить char * указатель на данные внутри ostringstream.
Если я сделаю следующее:
std::ostringstream ofs;
.....
const char *stam = (ofs.str()).c_str();
Существует копия содержимого строки в ofs.
Я хочу получить указатель на этот контент без копии.
Есть ли способ сделать это?
Хотя вы не можете получить указатель на буфер символов в ostringstream, вы можете получить доступ к его символам, не копируя их, если вы переключитесь на использование stringstream. Строковый поток допускает ввод и вывод (чтение и запись в поток), тогда как ostringstream разрешает только вывод (запись в поток). Пример:
std::stringstream ss;
ss << "This is a test.";
// Read stringstream from index 0. Use different values to look at any character index.
ss.seekg(0);
char ch;
while (ss.get(ch)) { // loop getting single characters
std::cout << ch;
}
ss.clear(); // Clear eof bit in case you want to read more from ss
Этот сайт имеет довольно хороший обзор струнных потоков и того, что вы можете с ними сделать.
Это фактически отвечает на вопрос … потребовалось некоторое время, но я хотел сделать это по тем же причинам (эффективность в сравнении с переносимостью подходит для моей ситуации):
class mybuf : public std::stringbuf {
public:
// expose the terribly named end/begin pointers
char *eback() {
return std::streambuf::eback();
}
char *pptr() {
return std::streambuf::pptr();
}
};class myos : public std::ostringstream {
mybuf d_buf;
public:
myos() {
// replace buffer
std::basic_ostream<char>::rdbuf(&d_buf);
}
char *ptr();
};
char *myos::ptr() {
// assert contiguous
assert ( tellp() == (d_buf.pptr()-d_buf.eback()) );
return d_buf.eback();
}
int main() {
myos os;
os << "hello";
std::cout << "size: " << os.tellp() << std::endl;
std::string dat(os.ptr(),os.tellp());
std::cout << "data: " << dat << std::endl;
}
Это еще раз указывает на более глубокую проблему, лежащую в основе стандартной библиотеки, — путаницу между контрактами и «безопасностью». При написании службы обмена сообщениями мне нужна библиотека с эффективными контрактами … а не с безопасностью. В других случаях, когда я пишу пользовательский интерфейс, я хочу сильной безопасности и меньше заботиться об эффективности.