У Стандартній бібліотеці С++ є окремий набір класів, які дозволяють використовувати вже знайомі нам оператори вставки (<<
) і вилучення (>>
) з рядками.
Потокові класи
Як і istream з ostream, так і потокові класи для рядків надають буфер для зберігання даних. Однак, на відміну від cin і cout, ці потокові класи не підключені до каналу вводу/виводу (тобто до клавіатури, монітора тощо).
Є 6 потокових класів, які використовуються для читання і запису рядків:
клас istringstream (є дочірнім класу istream);
клас ostringstream (є дочірнім класу ostream);
клас stringstream (є дочірнім класу iostream);
клас wistringstream;
клас wostringstream;
клас wstringstream.
Щоб використовувати клас stringstream, потрібно підключити заголовок sstream. Щоб додати дані в stringstream, ми можемо використати оператор вставки (<<
):
1 2 3 4 5 6 7 8 |
#include <iostream> #include <sstream> // для stringstream int main() { std::stringstream myString; myString << "Lorem ipsum!" << std::endl; // вставляємо "Lorem ipsum!" в stringstream } |
Або функцію str(string):
1 2 3 4 5 6 7 8 |
#include <iostream> #include <sstream> // для stringstream int main() { std::stringstream myString; myString.str("Lorem ipsum!"); // присвоюємо буферу stringstream рядок "Lorem ipsum!" } |
Аналогічно, щоб отримати дані назад з stringstream, ми можемо використати функцію str():
1 2 3 4 5 6 7 8 9 |
#include <iostream> #include <sstream> // для stringstream int main() { std::stringstream myString; myString << "336000 12.14" << std::endl; std::cout << myString.str(); } |
Результат:
336000 12.14
Або оператор вилучення (>>
):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
#include <iostream> #include <sstream> // для stringstream int main() { std::stringstream myString; myString << "336000 12.14"; // вставляємо (числовий) рядок в потік std::string part1; myString >> part1; std::string part2; myString >> part2; // Виводимо числа std::cout << part1 << " and " << part2 << std::endl; } |
Результат:
336000 and 12.14
Зверніть увагу, оператор вилучення (>>
) перебирає буфер, автоматично розбиваючи його на окремі значення за допомогою наявних пробілів (тобто одне використання оператора вилучення (>>
) дорівнює одному значенню з буфера). Тоді як функція str() повертає всі дані з потоку (не частково, а повністю), навіть якщо перед нею використовувався оператор вилучення.
Конвертація рядків у числа і навпаки
Ми можемо використовувати оператори вставки і вилучення з рядками для їх конвертації в числа і навпаки. Наприклад, конвертація чисел в рядки:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include <iostream> #include <sstream> // для stringstream int main() { std::stringstream myString; int nValue = 336000; double dValue = 12.14; myString << nValue << " " << dValue; std::string strValue1, strValue2; myString >> strValue1 >> strValue2; std::cout << strValue1 << " " << strValue2 << std::endl; } |
Результат:
336000 12.14
А тепер конвертація (числового) рядка назад в числа:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <iostream> #include <sstream> // для stringstream int main() { std::stringstream myString; myString << "336000 12.14"; // вставляємо (числовий) рядок в потік int nValue; double dValue; myString >> nValue >> dValue; std::cout << nValue << " " << dValue << std::endl; } |
Результат:
Очищення stringstream для повторного використання
Є кілька способів очистити буфер stringstream:
Спосіб №1: Використати функцію str() з пустим рядком C-style.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <iostream> #include <sstream> // для stringstream int main() { std::stringstream myString; myString << "Hello "; myString.str(""); // очищаємо буфер myString << "World!"; std::cout << myString.str(); } |
Спосіб №2: Використати функцію str() з пустим об’єктом std::string:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <iostream> #include <sstream> // для stringstream int main() { std::stringstream myString; myString << "Hello "; myString.str(std::string()); // очищаємо буфер myString << "World!"; std::cout << myString.str(); } |
Результат виконання вищенаведених програм:
World!
При очищенні stringstream непоганою ідеєю є виклик функції clear():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <iostream> #include <sstream> // для stringstream int main() { std::stringstream myString; myString << "Hello "; myString.str(""); // очищаємо буфер myString.clear(); // скидаємо всі флаги помилок myString << "World!"; std::cout << myString.str(); } |
Функція clear() скидає всі флаги помилок, які були раніше встановлені, і повертає потік назад в його колишній (без помилок) стан. Ми поговоримо детально про стани потоку і флаги помилок на наступному уроці.