C ++ и C файловый ввод / вывод - PullRequest
6 голосов
/ 03 марта 2009

Ввод / вывод файла C ++ сложнее, чем ввод / вывод файла C. Итак, в C ++ создание новой библиотеки для файлового ввода-вывода полезно или нет? Я имею в виду <fstream> Может кто-нибудь сказать, есть ли какие-либо преимущества в вводе-выводе файлов C ++?

Ответы [ 9 ]

14 голосов
/ 03 марта 2009

Мнение

Я не знаю ни одного реального проекта, использующего потоки C ++. Они слишком медленные и сложны в использовании. Есть несколько более новых библиотек, таких как FastFormat и версия Boost , которые утверждают, что они были лучше, в последнем журнале ACCU Overload была статья о них. Лично я использовал библиотеку c FILE последние 15 лет или около того в C ++, и я не вижу причин для изменений.

Скорость

Вот небольшая тестовая программа (я быстро собираюсь вместе), чтобы показать основные проблемы со скоростью:

#include <stdio.h>
#include <time.h>

#include<iostream>
#include<fstream>

using namespace std;

int main( int argc, const char* argv[] )
    {
    const int max = 1000000;
    const char* teststr = "example";

    int start = time(0);
    FILE* file = fopen( "example1", "w" );
    for( int i = 0; i < max; i++ )
        {
        fprintf( file, "%s:%d\n", teststr, i );
        }
    fclose( file );
    int end = time(0);

    printf( "C FILE: %ds\n", end-start );

    start = time(0);
    ofstream outdata;
    outdata.open("example2.dat");
    for( int i = 0; i < max; i++ )
        {
        outdata << teststr << ":" << i << endl;
        }
    outdata.close();
    end = time(0);

    printf( "C++ Streams: %ds\n", end-start );

    return 0;
    }

И результаты на моем ПК:

C FILE: 5s
C++ Streams: 260s

Process returned 0 (0x0)   execution time : 265.282 s
Press any key to continue.

Как мы видим, этот простой пример в 52 раза медленнее. Я надеюсь, что есть способы сделать это быстрее!

ПРИМЕЧАНИЕ: изменение endl на '\ n' в моем примере улучшило потоки C ++, сделав его всего в 3 раза медленнее, чем потоки FILE * (спасибо jalf ), могут быть способы сделать это быстрее.

Сложность использования

Я не могу утверждать, что printf () не является кратким, но он более гибок (IMO) и проще для понимания, как только вы пройдете начальный WTF для макросов.

double pi = 3.14285714;

cout << "pi = " << setprecision(5)  << pi << '\n';
printf( "%.5f\n", pi );

cout << "pi = " << fixed << showpos << setprecision(3) << pi << '\n'; 
printf( "%+.3f\n", pi );

cout << "pi = " << scientific << noshowpos << pi<< '\n';
printf( "%e\n", pi );

Вопрос

Да, возможно, есть необходимость в лучшей библиотеке C ++, многие из них FastFormat - это библиотека, покажет только время.

1044 * Дэйв *

7 голосов
/ 03 марта 2009

Снятие переполнения буфера кажется мне большой победой для C ++.

6 голосов
/ 03 марта 2009

В ответ на ответ Дэвида Аллана Финча я исправил ошибку в его коде бенчмаркинга (он сбрасывал поток в версии C ++ после каждой строки) и перезапустил тест:

Цикл C ++ теперь выглядит так:

start = time(0);
{
    ofstream outdata("example2.txt");
    for( int i = 0; i < max; i++ )
    {
        outdata << teststr << ":" << i << "\n"; // note, \n instead of endl
    }
}
end = time(0);

Я выполняю 10000000 итераций (в 10 раз больше, чем в исходном коде, потому что в противном случае числа слишком малы для паршивого разрешения time (), чтобы дать нам что-нибудь значимое)) И вывод:

G++ 4.1.2:
C FILE: 4s
C++ Streams: 6s

MSVC9.0:
C FILE: 10s
C++ Streams: 23s

(обратите внимание, версия MSVC была запущена на моем ноутбуке со значительно более медленным жестким диском)

Но это дает нам разницу в производительности в 1,5-2,3 раза, в зависимости от реализации. и другие внешние факторы.

6 голосов
/ 03 марта 2009

Пожалуйста, посмотрите на

http://www.ddj.com/cpp/184403651

тогда Вы предпочтете C ++ I / O, чем C I / O.

Короче С предпочтительнее, если вы знаете размер данных до чтения или записи и для скорости. C ++ предпочтительнее, если вы не знаете размер данных и эффективный код.

2 голосов
/ 03 марта 2009

Различия в производительности между форматами ввода-вывода printf () / fwrite и форматированием потоков ввода-вывода C ++ сильно зависят от реализации. Некоторые реализации (например, Visual C ++) строят свои потоки ввода-вывода поверх объектов FILE *, что приводит к увеличению сложности их реализации во время выполнения. Обратите внимание, однако, что не было особых ограничений для реализации библиотеки таким способом.

По моему мнению, преимущества ввода-вывода C ++ заключаются в следующем:

  • Введите безопасность, как уже было указано ранее.
  • Гибкость реализации. Код может быть написан для выполнения определенного форматирования или ввода в или из общего объекта ostream или istream. Затем приложение может вызвать этот код с любым видом производного объекта потока. Если код, который я написал и протестировал для файла, теперь необходимо применить к сокету, последовательному порту или некоторому другому внутреннему потоку, вы можете создать реализацию потока, специфичную для этого типа ввода / вывода. Расширение ввода / вывода в стиле C таким способом даже близко не возможно.
  • Гибкость в настройках локали: на мой взгляд, использование единой глобальной локали на C серьезно ошибочно. У меня были случаи, когда я вызывал библиотечный код (DLL), который изменял глобальные настройки локали под моим кодом и полностью испортил мой вывод. Поток C ++ позволяет вам использовать () любую локаль для объекта потока.
1 голос
/ 07 августа 2018

Когда мне нужно вводить / выводить данные в файле на C ++, я просто использую две строки.

freopen("input.txt","r",stdin); // for input from file
freopen("output.txt","w",stdout);// for output from file

Теперь вы можете сканировать переменные, как обычно, с консоли, и все, что вы печатаете как вывод, будет отображаться в файле output.txt.

Так что я не думаю, что файловый ввод / вывод в c ++ сложен, он намного проще, чем в c.

1 голос
/ 03 марта 2009

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

1 голос
/ 03 марта 2009

std :: ifstream и std :: ofstream уже находятся в библиотеке stl. Вам не нужно создавать свой собственный.

Основное преимущество - все выходы и входы относятся к типу безопасности.

0 голосов
/ 03 марта 2009

Много. Недостатки тоже. Смотрите FAQ по языку C ++ для подробностей. Вкратце: безопасность типов и определяемые пользователем типы.

...