В чем разница между istringstream, ostringstream и stringstream? / Почему бы не использовать stringstream в каждом случае?

Вы можете сделать это с помощью usort . Аргумент $cmp_function может быть:

function my_sorter($a, $b) {
    $c = strcmp($a['state'], $b['state']);
    if($c != 0) {
        return $c;
    }

    $c = strcmp($a['event_type'], $b['event_type']);
    if($c != 0) {
        return $c;
    }

    return strcmp($a['date_start'], $b['date_start']);
}

Для произвольного количества полей в PHP 5.3 вы можете использовать замыкания для создания функции сравнения:

function make_cmp($fields, $fieldcmp='strcmp') {
    return function ($a, $b) use (&$fields) {
        foreach ($fields as $field) {
            $diff = $fieldcmp($a[$field], $b[$field]);
            if($diff != 0) {
                return $diff;
            }
        }
        return 0;
    }
}

usort($arr, make_cmp(array('state', 'event_type', 'date_start')))

Для произвольное количество полей разных типов в PHP 5.3:

function make_cmp($fields, $dfltcmp='strcmp') {
    # assign array in case $fields has no elements
    $fieldcmps = array();
    # assign a comparison function to fields that aren't given one
    foreach ($fields as $field => $cmp) {
        if (is_int($field) && ! is_callable($cmp)) {
            $field = $cmp;
            $cmp = $dfltcmp;
        }
        $fieldcmps[$field] = $cmp;
    }
    return function ($a, $b) use (&$fieldcmps) {
        foreach ($fieldcmps as $field => $cmp) {
            $diff = call_user_func($cmp, $a[$field], $b[$field]);
            if($diff != 0) {
                return $diff;
            }
        }
        return 0;
    }
}

function numcmp($a, $b) {
    return $a - $b;
}
function datecmp($a, $b) {
    return strtotime($a) - strtotime($b);
}
/**
 * Higher priority come first; a priority of 2 comes before 1.
 */
function make_evt_prio_cmp($priorities, $default_priority) {
    return function($a, $b) use (&$priorities) {
        if (isset($priorities[$a])) {
            $prio_a = $priorities[$a];
        } else {
            $prio_a = $default_priority;
        }
        if (isset($priorities[$b])) {
            $prio_b = $priorities[$b];
        } else {
            $prio_b = $default_priority;
        }
        return $prio_b - $prio_a;
    };
}

$event_priority_cmp = make_evt_prio_cmp(
    array('meeting' => 5, 'party' => 10, 'concert' => 7), 
    0);

usort($arr, make_cmp(array('state', 'event' => $event_priority_cmp, 'date_start' => 'datecmp', 'id' => 'numcmp')))

144
задан Lii 1 February 2016 в 15:33
поделиться

7 ответов

Лично мне очень редко приходится выполнять потоковую передачу в один и тот же строковый поток и из него.

Обычно я хочу либо инициализировать поток из строки, а затем проанализировать его; или передавать вещи в строковый поток, а затем извлекать результат и сохранять его.

Если вы транслируете в один поток и из одного потока, вы должны быть очень осторожны с состоянием потока и позициями потока.

Использование «просто» istringstream или ostringstream лучше выражает ваше намерение и дает вам некоторую проверку против глупых ошибок, таких как случайное использование << vs ] >> .

Там могло быть некоторое улучшение производительности, но я бы не стал обращать внимание на это в первую очередь.

Нет ничего плохого в том, что вы написали. Если вы обнаружите, что он не работает достаточно хорошо, вы можете профилировать другие подходы, в противном случае придерживайтесь того, что является наиболее ясным. Лично я бы просто набрал:

std::string stHehe( "Hello stackoverflow.com!" );
110
ответ дан 23 November 2019 в 22:21
поделиться

A stringstream несколько больше, и может иметь несколько меньшую производительность - множественное наследование может потребовать корректировки указателя vtable. Основное различие заключается (по крайней мере, в теории) в лучшем выражении намерений и предотвращении случайного использования >> там, где предполагалось << (или наоборот). В то же время, разница достаточно мала, поэтому, особенно для быстрых кусков демонстрационного кода и тому подобного, я ленюсь и просто использую stringstream. Я не могу вспомнить, когда я в последний раз случайно использовал <<, когда хотел >>, так что для меня эта часть безопасности кажется в основном теоретической (тем более, что если вы сделаете такую ошибку, она почти всегда будет действительно очевидна почти сразу).

Нет ничего плохого в том, чтобы просто использовать строку, если это позволяет достичь того, чего вы хотите. Если вы просто собираете строки вместе, это просто и работает отлично. Если же вы хотите форматировать другие типы данных, stringstream будет поддерживать это, а строка, в основном, нет.

20
ответ дан 23 November 2019 в 22:21
поделиться

istringstream - для ввода, ostringstream - для вывода. stringstream - ввод и вывод. Вы можете использовать stringstream практически везде. Однако, если вы передадите свой объект другому пользователю, и он использует оператор >>, тогда как вы ждали объект только для записи, вы не будете счастливы ;-)

PS: ничего плохого в этом нет, просто проблемы с производительностью.

7
ответ дан 23 November 2019 в 22:21
поделиться

Предположительно, если для вашей операции подходит только вставка или только извлечение, вы можете использовать одну из версий с префиксом 'i' или 'o', чтобы исключить нежелательную операцию.

Если это не важно, то можно использовать версию i/o.

Конкатенация строк, которую вы показываете, вполне допустима. Хотя конкатенация с помощью строкового потока возможна, это не самая полезная особенность строковых потоков, которая заключается в возможности вставлять и извлекать POD и абстрактные типы данных.

1
ответ дан 23 November 2019 в 22:21
поделиться

Отвечу на ваш третий вопрос: Нет, это совершенно разумно. Преимущество использования потоков заключается в том, что вы можете вводить любое значение, для которого определен оператор << , в то время как вы можете добавлять только строки (C ++ или C) в std :: string .

2
ответ дан 23 November 2019 в 22:21
поделиться

Зачем открывать файл для чтения / записи, если, например, вам нужно только читать из него?

Что, если несколько процессов должны читать из одного и того же файла?

0
ответ дан 23 November 2019 в 22:21
поделиться

В большинстве случаев вам не понадобятся и ввод, и вывод в одном строковом потоке, поэтому использование std :: ostringstream и std :: istringstream явно указывает на ваше намерение чистый. Это также предотвращает случайный ввод неправильного оператора ( << vs >> ).

Если вам нужно выполнить обе операции в одном потоке, вы, очевидно, воспользуетесь версией общего назначения.

Проблемы с производительностью будут наименьшей из ваших проблем, ясность - главное преимущество.

Наконец, нет ничего плохого в использовании добавления строк, поскольку вам нужно создавать чистые строки. Вы просто не можете использовать это для объединения чисел, как в таких языках, как Perl.

15
ответ дан 23 November 2019 в 22:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: