c ++ 11 — Каковы исторические причины того, что scanf и printf не имеют аналогов в потоках C ++?

printf("%d: %d, %d\n", foo, bar, baz);

намного чище, чем

std::cout << foo << ": " << bar << ", " << baz << "\n";

и нет никакого очевидного способа вообще переписать

scanf("%d: %d, %d\n", &foo, &bar, &baz);

кроме, скажем

std::cin >> foo;
std::cin.ignore();
std::cin >> bar;
std::cin.ignore();
std::cin >> baz;
std::cin.ignore();

который уступает по понятным причинам.

Почему нет таких функций, как istream::scanf а также ostream::printf? Я не вижу никакой причины, почему следующее не должно было стать возможным:

std::cout.printf("%d: %d, %d\n", foo, bar, baz);
std::cin.scanf("%d: %d, %d\n", foo, bar, baz);

Я уверен, что кто-то должен был предложить это для стандарта в какой-то момент, и это должно быть отклонено. Зачем?

2

Решение

Во-первых, вы всегда можете использовать функции C из C ++.

Во-вторых, очень мало «настоящих» программ, использующих scanf, так как обычно вам нужно что-то, что дает вам больше контроля над тем, что вы читаете, и как отделить его от входных данных, которые вы не хотите читать. Программы читают из файлов, или, возможно, из какого-то пользовательского интерфейса, но редко из «стандартного ввода», и если они делают, как множество инструментов Unix, они обычно не используют scanf.

С printf, вероятно, просто не было никакой причины дублировать printf или sprintf в строку в классах C ++.

3

Другие решения

Вы все еще можете использовать printf а также scanf в C ++. Итак, какая польза от вашего предложения? Вы ничего не получаете, просто давая им разные имена.

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

C ++ аналог этих функций stringstream,

2

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

До C ++ 11 в C ++ не было безопасной конструкции типа variardic. Так что printf синтаксис был запрещен. Теперь вы можете подобраться ближе:

cpprintf("bob %s your %s! %d\n")<< "is" << "uncle" << 42;

где мы создаем объект форматирования, то << аргументы в это.

Недостатком здесь является то, что строка "bob… контролирует поток кода — код контроля данных был серьезным источником ошибок и эксплойтов.

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

Ох, и последняя проблема printf не позволяет объектам форматировать себя — он не расширяется пользователями printf.

2
По вопросам рекламы [email protected]