C - Яка різниця між istringstream,ostringstream та stringstream
Коли я використовуватиму std::istringstream , std::ostringstream і std::stringstream і чому я не повинен просто використовувати std::stringstream у кожному сценарії (чи є проблеми продуктивності під час виконання?).
Зрештою, щось погане в цьому (замість використання потоку взагалі):
Особисто я знаходжу дуже рідкісним, що хочу виконувати потокове і з того ж потоку рядків.
Зазвичай хочу чи ініціалізувати потік з рядка, та був аналізувати його; або передати речі в потік рядків, а потім отримати результат і зберегти його.
Якщо ви передаєте потоки в один потік з одного потоку, ви повинні бути дуже обережними з положенням потоку та позиціями потоку.
Використання 'just' istringstream або ostringstream краще висловлює ваші наміри та дає вам деяку перевірку проти дурних помилок, таких як випадкове використання vs >> .
Можливо, є деякі покращення продуктивності, але я б не став дивитися на них в першу чергу.
Немає нічого поганого у тому, що ви написали. Якщо ви виявите, що він не працює досить добре, ви можете продумати інші підходи, інакше дотримуйтесь того, що найкраще. Особисто я б просто пішов за:
A stringstream дещо більше і може мати дещо нижчу продуктивність - для множинного успадкування може знадобитися коригування покажчика vtable. Основна відмінність (принаймні теоретично) краще виражає ваші наміри та запобігає випадковому використанню >> , де ви мали намір (або навпаки). OTOH, різниця досить мала, що особливо для швидких фрагментів демонстраційного коду і т.д., Ялінивий і просто використовую stringstream. Я не можу згадати востаннє, коли я випадково використав , коли я мав намір >> , Так що для мене ця битка безпеки здається в основному теоретичною (тим більше, що якщо ви зробите таку помилку, вона майже завжди буде дійсно очевидно майже відразу).
Нічого поганого використання рядка, якщо вона виконує те, що ви хочете. Якщо ви просто вкладаєте рядки, це легко та чудово працює. Якщо ви хочете форматувати інші типи даних, то stringstream підтримуватиме це, а рядок в основному не буде.
У більшості випадків ви не потребуватимете як введення, так і виходу в тому ж рядку, тому використання std::ostringstream і std::istringstream явно робить ваш намір ясним. Це також заважає вам випадково ввести невірний оператор ( vs >> ).
Якщо вам потрібно виконати обидві операції в одному потоці, ви, очевидно, використовуватимете версію загального призначення.
Проблеми з продуктивністю були б найменшою з ваших проблем тут, ясність – головна перевага.
Нарешті, немає нічого поганого використання додавання рядка, оскільки вам потрібно побудувати чисті рядки. Ви просто не можете використовувати це, щоб комбінувати числа, як ви можете, такими мовами, як perl.
Інші вже обробили stringstream vs. [io]stringstream досить добре; мені не треба їхати туди.
Що стосується std::string - ну, я не вважаю, що він має оператори або >> тому ви не можете використовувати його там, де може знадобитися потік файлів. Що ще важливіше, я б очікував повторних і довільних конкатенацій для std::string , щоб мати продуктивність O(N2) або, у кращому випадку, продуктивність O(N*log(N)), причому різницяполягає в тому, наскільки обережний програміст повинен виділити зайву ємність у цільовому рядку. Тим не менш, N конкатенацій в ostringstream повинні мати продуктивність по O (N) (залишаючи осторонь довжину окремих рядків). Це може бути тривіальною різницею, коли ви об'єднуєте лише один або два рядки, а ostringstream може все ще повільніше, ніж std::string , коли N мало. Але я знаю випадки, коли N був дуже великим, і продуктивність O (N 2) справді хворіла.
istringstream для введення, ostringstream для виведення. stringstream - вхід та вихід. Ви можете використовувати stringstream майже скрізь. Однак, якщо ви передаєте свій об'єкт іншому користувачеві і використовуєте оператор → , тоді як очікуєте об'єкт тільки для запису, ви не будете щасливі; -)
PS: нічого поганого в цьому просто проблеми з продуктивністю.
Щоб відповісти на третє запитання: Ні, це цілком розумно. Перевага використання потоків полягає в тому, що ви можете ввести будь-яке значення, яке отримало operator , але ви можете додавати рядки (C++ або C) в std::string .
Імовірно, якщо для вашої операції підходить тільки вставка або витяг, ви можете використовувати одну з префіксних версій "i" або "o", щоб виключити небажану операцію.
Якщо це не має значення, ви можете використовувати версію i/o.
Конкатенація рядків, які ви показуєте, абсолютно коректна. Хоча можлива конкатенація з використанням рядкового потоку, яка не є найкориснішою функцією рядкових потоків, яка повинна мати можливість вставляти та вилучати POD та абстрактні типи даних.
Навіщо відкривати файл для доступу для читання та запису, якщо вам потрібно лише його прочитати?