簡體   English   中英

C++ 和 C 文件 I/O

[英]C++ and C file I/O

C++ 文件 I/O 比 C 文件 I/O 更難。 那么在 C++ 中,為文件 I/O 創建一個新庫是否有用? 我的意思是<fstream>誰能告訴我 C++ 文件 I/O 有什么好處嗎?

意見

我不知道任何使用C ++流的實際項目。 它們太慢並且難以使用。 有一些較新的庫,例如FastFormatBoost版本,聲稱更好,最近的ACCU Overload雜志中有一篇關於它們的文章。 我個人在C ++中使用c FILE庫已近15年了,我看不出有任何需要更改的理由。

速度

這是小的測試程序(我很快就湊齊了),以顯示基本的速度問題:

#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;
    }

結果在我的PC上:

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

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

如我們所見,這個簡單的例子要慢52倍。 我希望有一些方法可以使其更快!

注意:在我的示例中,將endl更改為'\\ n'改進了C ++流,使其速度僅比FILE *流慢3倍(感謝jalf ),有多種方法可以使其速度更快。

使用困難

我不能說printf()並不簡潔,但是一旦您通過了宏代碼的初始WTF,它就會更靈活(IMO)並且更易於理解。

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是該庫,只有時間能證明。

戴夫

對於我來說,消除緩沖區溢出對於C ++似乎是一個巨大的勝利。

請看看

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

那么您將更喜歡C ++ I / O而不是CI / O。

簡而言之,如果您知道讀寫之前和速度方面的數據大小,則首選C。 如果您不知道數據大小和高效代碼,則首選C ++。

為了回應David Allan Finch的回答,我修復了他的基准測試代碼中的一個錯誤(他在每行之后刷新了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倍,具體取決於實現方式。 和其他外部因素。

printf()/ fwrite樣式I / O和C ++ IO流格式之間的性能差異在很大程度上取決於實現。 一些實現(例如,Visual C ++)將其IO流構建在FILE *對象之上,這往往會增加其實現的運行時復雜性。 但是請注意,以這種方式實現庫沒有特別的限制。

我個人認為,C ++ I / O的好處如下:

  • 如前所述,輸入安全類型。
  • 實施的靈活性。 可以編寫代碼以對特定的ostream或istream對象進行特定的格式化或輸入。 然后,應用程序可以使用任何一種派生的流對象來調用此代碼。 如果現在將我針對文件編寫和測試的代碼需要應用於套接字,串行端口或其他某種內部流,則可以創建特定於該I / O的流實現。 以這種方式擴展C風格的I / O幾乎是不可能的。
  • 語言環境設置的靈活性:我認為使用單一全局語言環境的C方法存在嚴重缺陷。 我遇到過一些案例,在這些案例中,我調用了庫代碼(一個DLL),該代碼更改了代碼下的全局語言環境設置並完全弄亂了我的輸出。 C ++流允許您將任何語言環境注入()到流對象。

每當我需要在C ++中的文件中接受輸入/提供輸出時,我只需使用兩行。

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

現在,您可以像通常在控制台中一樣掃描變量,並且您作為輸出打印的任何內容都將顯示在output.txt文件中。

因此,我認為c ++中的文件I / O並不困難,它比c容易。

std :: ifstream和std :: ofstream已經在stl庫中。 您不必創建自己的。

主要優點是所有輸出和輸入均為類型安全。

C和C ++是兩種不同的語言。 C ++文件io會花費一些時間來習慣,但是一旦您使用算法,異常等,它們就會很自然地就位。

很多。 缺點也是。 有關詳細信息,請參見C ++語言常見問題解答。 簡而言之:類型安全和用戶定義的類型。

A more modern update.... ran similar code in Quick C++ Benchmarks with GCC 9.2 and now C++ iostream is showing as just slightly faster (1.1x) vs equivalent C IO. 注意:使用 "\n" 而不是 std::endl 來避免刷新問題。 圖表來自 Quick c++ Benchmarks和實際代碼

#include<iostream>
#include<fstream>

static void cIO(benchmark::State& state) {
  // Code inside this loop is measured repeatedly

  FILE *file{fopen("/tmp/example1.dat","w")};
  const char* teststr = "example";
  auto i{0};
  for (auto _ : state) {
   fprintf( file, "%s:%d\n", teststr, i++ );
  }
 fclose(file);
}
// Register the function as a benchmark
BENCHMARK(cIO);

static void cppIO(benchmark::State& state) {
  // Code before the loop is not measured
  std::ofstream outdata;
  outdata.open("/tmp/example2.dat");
  const char* teststr = "example";
  auto i{0};
  for (auto _ : state) {
   outdata << teststr << ":" << i++ << "\n";
  }
  outdata.close();
}
BENCHMARK(cppIO);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM