Подтвердить что ты не робот

Различная позиция вставки со строкой

Я изо всех сил пытаюсь понять различные типы поведения stringstream из следующего кода. Может ли кто-нибудь пролить свет на то, как работает поток внутри?

int main(){
    string str = "123";  
    stringstream ss(str);
    cout << ss.str() <<endl;  
    ss << str;
    cout << ss.str() <<endl;
} 

вывод:

123

123

int main(){
    string str = "123";  
    stringstream ss;
    ss << str;
    cout << ss.str() <<endl;  
    ss << str;
    cout << ss.str() <<endl;
} 

выход:

123

123123

4b9b3361

Ответ 1

Это потому, что фактическая позиция записи не обновляется, поэтому, когда вы в первом примере делаете

ss << str;

вы перезаписываете текущую строку.

Используйте флаг std::ios_base::ate для конструктора потока строк

std::stringstream ss(str,
    std::ios_base::in | std::ios_base::out | std::ios_base::ate);

чтобы расположить указатели чтения/записи в конце.

См. пример в эта ссылка.

И это похоже на то, что для всех потоков, когда вы открываете поток файлов, позиции также начинаются.

Ответ 2

std::stringstream объект внутренне запоминает позицию, в которой письмо заканчивалось в последний раз. Это обновляется при использовании оператора <<, но не при использовании некоторой строки для создания этого потока:

stringstream ss(str);
cout << ss.tellp() <<endl;  
ss << str;
cout << ss.tellp() <<endl;

выходы:

0
3

то есть. к моменту выполнения первого ss << str; он просто использует "123" для перезаписи "123", который уже существует. Вы можете использовать setp для установки положения, в которое должен быть вставлен следующий символ:

stringstream ss(str);
cout << ss.str() <<endl;  
ss.seekp(3);                 // <-- sets outPUT position
ss << str;
cout << ss.str() <<endl;

В качестве альтернативы вы можете установить режим, который будет гарантировать, что это положение будет установлено до конца перед каждой операцией записи с помощью std::stringstream::app или вы можете использовать std::ios_base::ate, который ищет конец потока сразу после открытия:

stringstream ss(str, std::stringstream::out | std::stringstream::app);

Ответ 3

Построение std::stringstream устанавливает позицию в начало потока. Позиция обновляется после записи в поток или при вызове соответствующего метода поиска.