• ベストアンサー

C++でfprintfやprintf,fopenなどを使うのは好ましくない?

今までCは多少慣れがあり、一方でC++はごく最近始めました。 CとC++でパッと見明らかに違うのが入出力の関数とストリームだと思うのですが どうも私的にはCで使いっていたfprintfなどが使いやすいと思ってしまいます。 実数の表示の小数点以下の桁の指定とか、fprintf("xxxx%.3f")としたほうが ラクチンではないでしょうか? ただEffective C++などを見た感じC++ではC++のやり方のほうが良い とか書いてあってやはりそういうもんなのかなぁと。 それなら多少C++の利便性を切り捨ててでもCでやるかなぁと 思ってしまうのですが。。。 アドバイスいただけたら幸いです。お願いいたします。

  • R-gray
  • お礼率41% (1005/2413)

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

C++で printf() などを使うのは一概に悪いというわけではありません。 最低限、混在して使わなければ、まずはOKです。 ただ、ひとつ考えて欲しいのは、 > fprintf("xxxx%.3f") としたほうが楽 なのは、単に、これまでCで使い慣れていたからという理由に過ぎません。本質的にそちらの方が楽というわけではないのです。 一方で、printf() 系列の問題点というのは、可変引数関数なので、引数の型判定が実行時にしかわからないという点があります。 int i; printf("%f", i); などとして、表示がおかしいのに悩んだりするのはよくあることです。 また、決定的なこととして、C++では、クラスという「自前の型(ちょっと違う)」を作ることができます。これは、printf() では直接扱うことができません。 しかし、 class myClass; // 適切に << を定義する myClass aInstance; int i; cout << aInstance << " → " << i << "\n"; のように、C++流のストリームを使えば、それらも統一的に扱うことができます。 また、引数の型が異なっても適切に処理されます。 このようなことを含めて、C++のパワーを使うには、C++の流儀が良いということです。

その他の回答 (3)

  • aid-u
  • ベストアンサー率75% (22/29)
回答No.4

C++でのprintf()の使用ですが、型チェックの問題があることを認識したうえで使用することは問題ないと思います。 これは、printf()が実用上で有用な関数だと考えるためです。 型のチェックについては、コンパイラを含めたツールで対応できるのではないでしょうか。 gccではワーニングレベルの指定により、型が一致しない場合にワーニングを出せます。 printf()は、他の言語に取り入れられていることからも有用であることが推測できます。 以下はprintf()が取り入れられている言語の一部です。調べればもっと増えると思います。  ・Perl  ・Ruby  ・Java  ・OCaml Javaは、J2SE 5.0になってから取り入れられています。 また、OCamlは型チェックが厳しい言語でprintf()の仕様とは相性が悪そうですが、 強引(と私は思う)な方法で、取り入れています。 これらのことは、言語を設計する方がprintf()を実用的な関数と判断したためだと思います。

R-gray
質問者

お礼

みなさん丁寧な解説ありがとうございました。 割合いろんな流儀があるのですね。 少し納得できました。ありがとうございました!

回答No.3

批判の嵐を恐れずに、あえて書くと、、、 最近C++は、「落ち目」だとか、「斜陽」だとか言われます。 そう言われるには、それだけの複合的な要因があるのでしょうが、私は、「上位互換性」の問題は、大きいと思います。 C++でCのコードが使えます、VC++はC++のコードもCのコードも使えます、というのは、たいへんなメリットなのですが、現実に何が起きているかというと、「古いものが幅を利かせる」ということになってしまっています。 キャリアの長い、「教える立場」の人たちの中には、いつまでも古臭いコードに執着して、新しいものを頭ごなしに否定する、というようなこともあります。 たとえば、「MFCをいくらやっても本質がわからない」というのは、核心をついた指摘ですが、だからといってMFCそのものを否定してしまっては、進歩がありません。 その結果、マイクロソフトが、MSDNの中で「今後FMCのサポートをしない」なんてことを、大きな字で書くような事態になりました。 古いものに執着する人には都合がいいでしょうが、生産性を考えれば、今どきMFC抜きでC++の全てをまかなうことはできません。 C++やVC++が使われなくなってきている背景には、そうした混乱もあると思います。 その点、Javaなどは、バージョンが上がるたびに、「ご破算では」ということになりますから、みんな「横並び一線」です。 そんなことで、今後本格的にC++に取り組む、ということだったら、積極的に新しいものにチャレンジする姿勢のほうが、いいのではないでしょうか。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

場合場合での使い分けですね。 分かりやすい例でいうと、デストラクタ内や例外ハンドラ(catch節)でログを吐かせるような場合、(少なくとも私は)fprintfやfputsなどを使っています。そんなところで例外を送出するかもしれないC++のストリームは使いたくないからです(fprintfなどを使っても、no-fail保障まではできませんが、ログ出力ならそれでも済んでしまうので)。 > どうも私的にはCで使いっていたfprintfなどが使いやすいと思ってしまいます。 > 実数の表示の小数点以下の桁の指定とか、fprintf("xxxx%.3f")としたほうが > ラクチンではないでしょうか? これは間違いありません。 boost::formatを使うと幸せになれる可能性大ですので、調べてみることをお勧めします。

関連するQ&A

  • linux RedHatでC言語

    整数、単精度(float)、倍精度(double)の変数変換、各種書式付出力について教えてください。 また、よろしければ、40桁の整数、有効数字20桁の実数、小数点以下15桁の実数を表示する方法について教えてください。 本当にC言語の初歩だとは思いますが教えてください。

  • 小数が、18行x72列、並んでいるファイルを読みます。どうしたら良いでしょうか。

    ・小数が、72列18行あります。 ・小数は、ときに負号が記載されていることがあります。 ・小数は、C言語でfprintfで、"%-7.5f " で打ち出したもので、見てみると、7桁、時に八桁のようですが。 ・区切りは、上記のように空白一つで、fprintfで書き出したはずなのですが、実際には、スペースが一つか二つ(不定。どうやら負号のない場合には空白が一つ増える・・・ということみたいですが不明)入っています。 ・72列のデータの後はすぐに改行しておらず、スペースが一つか二つはいって、改行しています。 自分で書き出したデータなのに間抜けなことですが、どうしたらC言語で安定して、読み込めるでしょうか。 fgets? fgetc? scanfは不安です。 windows2002, thinkpad, borland C v5.5無料版です。 どうぞよろしくお願いいたします。

  • 最大50桁の実数の和・差・積を求めたい

    C++で、2つの最大50桁の実数を入力して、その和・差・積を求めるプログラムを作りたいのです。 実数をchar型に入力させて、それを1桁ずつint型に変換したいのですが、どのようにやればよいのでしょうか? また、その際、符号や小数点はどうすればよいのでしょうか? 計算の流れとしては、 ○足し算 小数点を合わせる ⇒下位の桁から1桁ずつ足し算していく ⇒結果が10以上の場合、10を引き、左隣の桁の数字に1を加える ○引き算 小数点を合わせる ⇒下位の桁から1桁ずつ引き算していく ⇒引かれる数字のほうが引く数字より小さい場合、引かれる数字に10を足し、左隣の桁の引かれる数字から1を引く というような感じで考えているのですが、小数点の合わせ方がわかりません。 また、掛け算に関しては、筆算の要領でやろうと思うのですが、どのようにやればよいのでしょうか? 私はC++の勉強歴が短いので、できれば初心者向けのわかりやすい説明でお願いします。

  • printf,fprintfって・・・

    こんにちは。 お恥ずかしいのですが、printfとfprintfの相違点は何でしょうか? 初心者にも分かるよう解説お願いします。

  • 小数点以下を強引に表示させたい

    小数点以下を強引に表示させたいと考えています。 具体的には、「130」という値を「130.00」というように、小数点以下2桁まで表示させたいのです。3桁以下は切り捨てます。 これまでは、 $c = $a / $b; round($c, 2); という方法でやっていたのですが、$cがきっちり割り切れる値だと、どうも普通に小数点以下を表示させないようなのです。 例え「00」でも表示させたいのですが、そのような関数はありますでしょうか? よろしくお願いいたします。

    • ベストアンサー
    • PHP
  • C言語の入出力関数の違い

    C言語を勉強しています。 自分が知っている入出力を行う関数は printf scanf fprintf fscanf sprintf sscanf gets puts getc putc fgets fputs fgetc fputc なのですがそれぞれのメリット・デメリットの違いがまだあいまいです。 というかまだ上の4つくらいしかまともに使ったことがありません。 自分の考えでは、 ・上の4つは書式を指定でき、ファイルから読み込みするときなどは fgetsよりもfscanfが使いやすいと思っています。 ・スペースを読み込みたいときはscanfではなくgetsを使わなければならない。 ・システム開発でscanfを使うことは危険なのでほとんどない。 間違った考え方をしていたり、どのようなデータのときに どの関数を使うのが正しい、常識、と知っている方いらっしゃいましたら 教えてください。

  • C++でのdouble型データの精度

    こんにちは。 コンパイラは、Borland C++ Compiler 5.5 を使っています。 表題の「精度」とは、 正確な値が保証される、「整数部分の桁数」+「小数点以下の桁数」 の事です。 普通、double型データの「精度」は、16桁であると認識しています。 そのため、例えば、 a=123456789012345.6 という浮動小数点数は16桁なので、正しい値が保証されるはずです。 ところが、printf("%f", d1); のようにprintf関数で表示すると、 123456789012345.593800 と表示されました。 これは、d1が正しい値を保持できていないという事です そこで、桁数を下げていった所、 a=1234567890.1 つまり、精度は11桁しかないという事になります。 何か僕が勘違いしているのでしょうか? それとも、僕が使っているコンパイラの精度が11桁しかないという事なのでしょうか? 何かお分かりの方がいらっしゃれば、是非アドバイスを頂きたいと思います。 では、よろしくお願い致します。

  • gnuplotをC言語で操作する方法

    C言語を用いてgnuplotを操作しデータファイルから自動的にグラフを作成するプログラムを作ろうとしています。 使用環境はWindows7、VisualStudio2010です。 ほとんどの部分はうまくいったのですが一部分が正しく表示されません。 軸の目盛ラベルの表示フォーマット設定のコマンドで set format x "%.1f" として小数点以下一桁を強制的に表示させるためC言語でパイプを用いて #define GNUPLOT_PATH "C:/gnuplot/binary/pgnuplot.exe" int plot(char *file_name){ FILE *gp; gp = _popen(GNUPLOT_PATH, "w"); fprintf(gp, "set title 'TEST PLOT'\n"); : (中略) : fprintf(gp, "set format x '%.1f' \n");//この部分が正しく反映されません。 : (中略) : fprintf(gp, "plot '%s' using 1:2 with linespoints lt 4 lw 5 pt 6 ps 2.0 lc rgb 'red'\n",file_name); fprintf(gp,"quit \n"); fflush(gp); _pclose(gp); return 0; } '%.2f' の部分をいろいろいじってみたのですがうまくいかず、なぜできないのか原因がわかりません。 fprintf()の数値代入の %f と混ざってしまっているのでしょうか?

  • 小数点の桁数ってなんて言いましたっけ?

    0.001 という数値から小数点3桁の3を算出したいんですが、この3の事をなんて言いましたっけ? 10のマイナス3乗?指数?Log10? またC#でこの値を簡単に出す関数なんてありましたでしょうか?

  • エクセル2000 電話番号の市外局番を入れたFAX番号を表示したい

    市外局番からの電話番号と隣の列に市外局番を抜いた(同じ番号なので)FAX番号のデータが入っております。         A        B      電話番号    FAX番号 1 XXX-XXXX-XXXX XXXX-XXXX 2 XXX-XXXX-XXXX XXXX-XXXX と言った具合になります。 これを、C列に市外局番を加えたFAX番号を表示するようにしたいので、C1に=LEFT(A1,4)&B1といれて、そのままオートフィルをかけたのですが、地域によって市外局番が2~5桁ありますので、市外局番が3桁以外の部分は目で見てLEFT関数の桁数を打ち変えております。 これを関数か何かで一括で出来る方法はないものかと思い質問させていただきました。        A          B         C      電話番号    FAX番号    FAX番号2 1 XXX-XXXX-XXXX XXXX-XXXX XXX-XXXX-XXXX  2 XXX-XXXX-XXXX XXXX-XXXX XXX-XXXX-XXXX  最終的に上のような形にしたいのです。 この一覧表は変わることがありますし、データが追加されるときはデータの一番下にあるわけではないので、変わるたびに一から入力しなおさなければなりません。 -の前の数字(市外局番)を数えられればいいと思うのですが、それをカウントできるやり方はあるのでしょうか? よろしくお願い致します。