Какой библиотекой C I/O нужно пользоваться в коде C++? [закрытый]

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

См. также: A хороший список лучших практик

Я бы добавил, очень важно, хорошо использовать модификатор final. Использование "окончательной" модификатор, когда это применимо в Java

Сводка:

  1. Используйте модификатор final для обеспечения хорошей инициализации.
  2. Избегайте возврата null в методы, например, при возврате пустых коллекций.
  3. Использовать аннотации @NotNull и @Nullable
  4. Быстрое завершение работы и использование утверждений, чтобы избежать распространения нулевых объектов через все приложение, когда они не должен быть пустым.
  5. Сначала используйте значения с известным объектом: if("knownObject".equals(unknownObject)
  6. Предпочитают valueOf() поверх toString ().
  7. Используйте null safe StringUtils StringUtils.isEmpty(null).

33
задан Community 1 May 2014 в 22:46
поделиться

12 ответов

Отвечать на исходный вопрос:
Что-либо, что может быть сделано с помощью stdio, может быть сделано, пользуясь iostream библиотекой.

Disadvantages of iostreams: verbose
Advantages    of iostreams: easy to extend for new non POD types.

шаг вперед переданный C C++ был безопасностью типов.

  • iostreams был разработан, чтобы быть явно безопасным с точки зрения типов. Таким образом присвоение на объект явно проверило тип (во время компилятора) объекта, присваиваемого также (генерирующий ошибку времени компиляции при необходимости). Таким образом предотвратите переполнения памяти во время выполнения или запись значения плавающего к символьному объекту и т.д.

  • , scanf ()/printf () и семья, с другой стороны, полагаются на программиста, получающего корректную строку формата и не было никакой проверки типа (я полагаю, что gcc имеет расширение, которое помогает). В результате это был источник многих ошибок (поскольку программисты менее прекрасны в своем анализе, чем компиляторы [не собирающийся говорить, что компиляторы прекрасны просто лучше, чем люди]).

Просто для уточнения комментарии от Colin Jensen.

  • iostream библиотеки были стабильны начиная с выпуска последнего стандарта (я забываю фактический год, но приблизительно 10 лет назад).

Для разъяснения комментариев Mikael Jansson.

  • другие языки, что он упоминает, что используют стиль форматирования, имеют явные гарантии для предотвращения опасных побочных эффектов C stdio библиотека, которая может (в C, но не упомянутые языки) вызывают катастрофический отказ во время выполнения.

N.B. я соглашаюсь, что iostream библиотека находится немного на подробной стороне. Но я готов выносить подробность для обеспечения безопасности во время выполнения. Но мы можем смягчить многословие при помощи Библиотека Формата Повышения .

#include <iostream>
#include <iomanip>
#include <boost/format.hpp>

struct X
{  // this structure reverse engineered from
   // example provided by 'Mikael Jansson' in order to make this a running example

    char*       name;
    double      mean;
    int         sample_count;
};
int main()
{
    X   stats[] = {{"Plop",5.6,2}};

    // nonsense output, just to exemplify

    // stdio version
    fprintf(stderr, "at %p/%s: mean value %.3f of %4d samples\n",
            stats, stats->name, stats->mean, stats->sample_count);

    // iostream
    std::cerr << "at " << (void*)stats << "/" << stats->name
              << ": mean value " << std::fixed << std::setprecision(3) << stats->mean
              << " of " << std::setw(4) << std::setfill(' ') << stats->sample_count
              << " samples\n";

    // iostream with boost::format
    std::cerr << boost::format("at %p/%s: mean value %.3f of %4d samples\n")
                % stats % stats->name % stats->mean % stats->sample_count;
}
39
ответ дан 11 revs, 2 users 98% 27 November 2019 в 17:32
поделиться

Это является просто слишком подробным.

Обдумывают конструкцию iostream для того, чтобы сделать следующее (так же для scanf):

// nonsense output, just to examplify
fprintf(stderr, "at %p/%s: mean value %.3f of %4d samples\n",
    stats, stats->name, stats->mean, stats->sample_count);

, Который был бы, требует чего-то как:

std::cerr << "at " << static_cast<void*>(stats) << "/" << stats->name
          << ": mean value " << std::precision(3) << stats->mean
          << " of " << std::width(4) << std::fill(' ') << stats->sample_count
          << " samples " << std::endl;

Строковое форматирование является случаем, где объектно-ориентированность может и должна быть, обошедшая в пользу форматирования DSL, встроенный в строки. Рассмотрите Lisp format, форматирование printf-стиля Python, или PHP, Bash, Perl, Ruby и их строка intrapolation.

iostream для того варианта использования дезинформирован, в лучшем случае

16
ответ дан Mikael Jansson 27 November 2019 в 17:32
поделиться

Библиотека Формата Повышения обеспечивает безопасную с точки зрения типов, объектно-ориентированную альтернативу для строкового форматирования printf-стиля и является дополнением к iostreams, который не страдает от обычных проблем многословия из-за умного использования % оператора. Я рекомендую рассмотреть его по использованию плоскости C printf, если Вам не нравится форматировать с operator< iostream; <.

14
ответ дан KK. 27 November 2019 в 17:32
поделиться

Назад в плохие былые времена, комитет по Стандартам C++ продолжал слоняться без дела с языком, и iostreams был движущейся целью. При использовании iostreams Вам тогда дали возможность переписывать части Вашего кода каждый год или около этого. Из-за этого я всегда использовал stdio, который не изменился значительно с 1989.

, Если бы я делал материал сегодня, я использовал бы iostreams.

9
ответ дан Colin Jensen 27 November 2019 в 17:32
поделиться

Если, как я, Вы изучили C прежде, чем изучить C++, stdio библиотеки кажутся более естественными для использования. Существуют за и против для iostream по сравнению с stdio, но я действительно пропускаю printf () при использовании iostream.

6
ответ дан Adam Pierce 27 November 2019 в 17:32
поделиться

В принципе я использовал бы iostreams, на практике я делаю слишком много отформатированные десятичные числа, и т.д. которые делают iostreams слишком нечитабельный, таким образом, я использую stdio. Повышение:: формат является улучшением, но не совсем мотивирующий достаточно для меня. На практике stdio почти безопасен с точки зрения типов, так как большинство современных компиляторов делает проверку аргументов так или иначе.

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

5
ответ дан Dan Hewett 27 November 2019 в 17:32
поделиться

Для двоичного IO я склонен использовать освобожденный stdio's и fwrite. Для отформатированного материала я буду обычно использовать Поток IO, хотя, поскольку Mikael сказал, non-trival (не по умолчанию?) форматированием может быть ЛАВАШ.

4
ответ дан Evan 27 November 2019 в 17:32
поделиться

Я использую iostreams, главным образом потому что это облегчает играть с потоком позже (если мне нужен он). Например, Вы могли узнать, что хотите отобразить вывод в некотором окне трассировки - это относительно легко сделать с судом и cerr. От курса, можно играть с каналами и материалом на Unix, но это не столь портативно.

я действительно люблю подобное printf форматирование, таким образом, я обычно форматирую строку сначала, и затем отправляю ее на буфер. С QT я часто использую QString:: sprintf (хотя они рекомендуют использовать QString:: аргумент вместо этого). Я посмотрел boost.format также, но не мог действительно привыкнуть к синтаксису (слишком многие % 's). Я должен действительно посмотреть на него, все же.

2
ответ дан Jan de Vos 27 November 2019 в 17:32
поделиться

То, что я пропускаю о iolibraries, является отформатированным входом.

iostreams не имеет хорошего способа копировать scanf () и даже повысить, не имеет необходимого расширения для входа.

2
ответ дан 27 November 2019 в 17:32
поделиться

stdio лучше для чтения двоичных файлов (как freading блоки в vector< неподписанный char> и использование .resize () и т.д.). Посмотрите, что read_rest функционирует в file.hh в http://nuwen.net/libnuwen.html для примера.

потоки C++ могут дросселировать на большом количестве байтов при чтении двоичных файлов, вызывающих ложь eof.

1
ответ дан Shadow2531 27 November 2019 в 17:32
поделиться

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

, Но если Вы хотите придерживаться с *printf функции, по-моему, не может быть никакой проблемы.

1
ответ дан INS 27 November 2019 в 17:32
поделиться

Несмотря на то, что API iostreams C ++ дает множество преимуществ, одна существенная проблема связана с i18n. Проблема в том, что порядок замены параметров может варьироваться в зависимости от культуры. Классический пример выглядит примерно так:

// i18n UNSAFE 
std::cout << "Dear " << name.given << ' ' << name.family << std::endl;

Хотя это работает для английского языка, на китайском имя фамилии стоит на первом месте.

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

boost :: format, кажется, сочетает в себе лучшее из stdio (единая строка формата, которая может использовать параметры в другом порядке, чем они появляются) и iostreams (безопасность типов, расширяемость ).

3
ответ дан 27 November 2019 в 17:32
поделиться
Другие вопросы по тегам:

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