Я написал следующий тестовый код:
int main(int argc, char* argv[]) {
stringstream ss;
int num;
ss << "54321";
ss >> num;
ss.str("");
ss << "12345";
ss >> num;
fprintf(stderr, "%d\n", num);
}
К моему удивлению, результат составил 54321. Как правильно перезаписать переменную с помощью оператора извлечения (>>)?
После первого извлечения вы достигли конца потока, поэтому eofbit
получил, и второе извлечение не удалось.
int main(int argc, char* argv[]) {
stringstream ss;
int num;
ss << "54321";
ss >> num;
// eofbit was set above,
// we need to clear it
ss.clear();
ss.str("");
ss << "12345";
ss >> num;
fprintf(stderr, "%d\n", num);
}
Вызов clear()
функция-член перед попыткой второго извлечения. Вторая проблема — это положение внутреннего указателя get, который не будет сброшен автоматически. использование seekg()
установить это.
РЕДАКТИРОВАТЬ: пораженные вещи не являются необходимыми, объяснил Вот.
Когда поток достигает конца потока, std::ios_base::eofbit
устанавливается Перед попыткой извлечь какую-либо дату, извлечение проверяет, установлен ли какой-либо флаг состояния, и, если это так, ничего не делает, и ваше извлечение завершается неудачно:
std::stringstream ss;
ss << "54321";
ss >> num; // sets eof:
std::cout << "eof: " << ss.eof() << "\n";
Чтобы поток делал что-либо после установки любого из флагов состояния, вам необходимо сначала очистить флаги:
ss.clear();
ss << "12345";
if (ss >> num) {
std::cout << "num=" << num << "\n";
}
else {
std::cout << "failed to extract a value\n";
}
Лично я обычно не использую операторы вывода для установки содержимого потока строки. Вместо этого я обычно использую str()
член:
std::ostringstream out; // note: this is just an output string stream
...
out.clear(); // the clear is still needed
out.str("12345");