Какая польза от «концов» в наши дни?

Пару дней назад я обнаружил небольшую ошибку, когда код выглядел примерно так:

ostringstream ss;
int anInt( 7 );

ss << anInt << "HABITS";
ss << ends;
string theWholeLot = ss.str();

Проблема заключалась в том, что ends вставлял '\ 0' в ostringstream, поэтому theWholeLot на самом деле выглядел как "7HABITS\0" (т.е. ноль в конце)

Теперь этого не было, потому что theWholeLot тогда использовался для взятия части const char * с использованием string::c_str(). Это означало, что нуль был замаскирован, поскольку он стал просто разделителем. Однако, когда это изменилось, чтобы использовать строки повсюду, ноль внезапно означал что-то и сравнения, такие как:

if ( theWholeLot == "7HABITS" )

потерпит неудачу. Это заставило меня задуматься: предположительно, причина ends - это возврат к временам ostrstream, когда поток обычно не завершался нулевым значением и должен был быть таким, чтобы str() (который затем отбрасывал не string, а char *) работал правильно .

Однако теперь, когда невозможно исключить char * из ostringstream, использование ends не только излишне, но и потенциально опасно, и я подумываю удалить их все из кода моих клиентов.

Может ли кто-нибудь увидеть очевидную причину использования ends в среде только std::string?


person Component 10    schedule 25.02.2010    source источник
comment
Моя единственная придирка была бы в том, что такое среда только std :: string? Любая нетривиальная программа использует аргументы системного вызова char * и т. Д. Тем не менее, есть полдюжины других способов справиться с этим, и конец имеет незначительную полезность.   -  person Duck    schedule 26.02.2010
comment
Вот некоторые примеры использования std::ends: http://stackoverflow.com/questions/624260/how-to-reuse-an-ostringstream/624291#624291   -  person Johannes Schaub - litb    schedule 26.02.2010
comment
Это не только для струнных. Это полезно для обычных потоков. Некоторым инструментам unix в качестве терминаторов требуются нулевые байты. cout << ends; предоставит их.   -  person Johannes Schaub - litb    schedule 26.02.2010
comment
OK. Я предполагаю, что моя точка зрения на самом деле заключается в том, что если у вас есть поток ostring, вы можете получить std :: string (но не c-строку с завершающим нулем), а если у вас есть std :: string, вы можете получить c-строку с нулевым завершением. Другими словами, на самом деле довольно сложно на этом маршруте получить строку, которая не завершается нулем, но вы можете непреднамеренно получить ненужный, нежелательный и трудно обнаруживаемый null ins std :: нить.   -  person Component 10    schedule 27.02.2010
comment
Спасибо за ссылку, Йоханнес, вы совершенно правы насчет API и т. Д., Которым нужны нули в данных и т. Д. Я думаю, что если бы я создавал такую ​​строку, у меня могло бы возникнуть соблазн вставить нуль напрямую (т.е. '\ 0', а не концы), поскольку хотя они оба делают одно и то же, '\ 0' прямо не означает конец как таковой.   -  person Component 10    schedule 27.02.2010


Ответы (2)


Вы, по сути, ответили на свой вопрос настолько подробно, насколько это необходимо. Я, конечно, не могу придумать никакой причины использовать std::ends, когда std::string и std::stringstream справятся со всем этим за вас.

Итак, чтобы прямо ответить на ваш вопрос, нет, нет причин использовать std::ends в среде только std::string.

person Peter Alexander    schedule 26.02.2010
comment
Я бы сказал, что нет причин использовать std::ends период. Я бы сказал, что я очень опытный программист на C ++, но даже не знал, что он существует. - person Thomas Bonini; 26.02.2010
comment
@Andreas, за то, что вы только что услышали об этом в первый раз, вы очень уверены в этом :) - person Johannes Schaub - litb; 26.02.2010
comment
Как указал Йоханнес, причин для этого достаточно. Для многих программ UNIX требуется общий терминатор '\ 0', например для передачи текста с символами ASCII ‹= 32 в другие программы. Я даже не могу представить себе жизнь без find -print0, xargs --null или read -d '\0', и это лишь некоторые из них. Также многие API требуют '\ 0'. Это общий терминатор строки, а строки являются наиболее важными элементами данных, поскольку в строку можно преобразовать все, что угодно. Поэтому вы хотите, чтобы строки были максимально гибкими. - person Andreas Spindler; 26.01.2012

Существуют некоторые API-интерфейсы, которые ожидают «строкового массива» с несколькими строками, завершающимися нулем, и двойным нулем для обозначения конца. Рэймонд Чанг недавно писал об этом в блоге, больше всего чтобы продемонстрировать, как часто с этим сталкиваются.

person Hans Passant    schedule 26.02.2010