iostream の便利さが理解できない – プログラミング – Home

iostream の便利さが理解できな...
 
通知
すべてクリア

[解決済] iostream の便利さが理解できない


tib
 tib
(@tib)
ゲスト
結合: 22年前
投稿: 468
Topic starter  

C++を使うようになって何年も経ちますが、未だにまともに使った事がないのが
「iostream」です。

私がC++を囓った初日に、ものの本に「型の安全性からもprintf()ではなくiostreamを使
うようにしましょう」といったようなことを書いていたと記憶していますが、例えば

double dPI = 3.1415926535;
double dE = 2.7182818284;

が与えられていたとして、

( 3.14159, 2.71828)

と標準出力に出力するのにも、これまで

printf( (%8.5f,%8.5f)\n, dPI, dE );

で済んでいたものを

cout << (;
cout.width( 8 ); cout.precision( 6 ); cout << dPI;
cout << ,;
cout.width( 8 ); cout.precision( 6 ); cout << dE;
cout << ) << endl;

としなくてはならない、と知って「可読性を落とすにも程がある」と投げ出してしまった
のです。

こうまでしてiostreamを使うメリットってどこにあるのでしょう?
それとも実はもっとスッキリ書く方法があるのでしょうか。


引用未解決
トピックタグ
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 1301
 

#include <iostream>
#include <iomanip>

using namespace std;

int main() {
double dPI = 3.1415926535;
double dE = 2.7182818284;

cout << '(' << setprecision(6)
<< setw(8) << dPI << ','
<< setw(8) << dE << ')'
<< endl;
return 0;
}


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 21年前
投稿: 600
 

> こうまでしてiostreamを使うメリットってどこにあるのでしょう?

ユーザ定義型に対しても operator << が定義できる。

complex<double> z(3.14, 2.78);
cout << z << endl;

とか。


返信引用
PATIO
(@patio)
Famed Member
結合: 3年前
投稿: 2660
 

既にεπιστημηさんが書かれていますけれど、
処理子(setwとか、setprecisionとかがそうです)を使えば、
そう見づらくもないと思います。
可読性は結局慣れの問題もあるのでC++の書き方が見づらいとは言い切れないと思いますし、
printf( (%8.5f,%8.5f)\n, dPI, dE );が可読性が高いと感じているのは
C言語にどっぷり浸かっていた所為だと思いますよ。
それにprintfを使っていたのでは、クラスのおいしい所が生きてきませんから。
(επιστημηさんのoperator <<が定義できるという話です。)


返信引用
Kazuki
 Kazuki
(@Kazuki)
ゲスト
結合: 22年前
投稿: 41
 

こういうのも便利ですよね。
void WriteToStream(std::ostream &os)
{
os << Hello world;
}

int main()
{
WriteToStream(std::cout); //標準出力にも
std::ostringstream oss;
WriteToStream(oss); //文字列にも
std::ofstream ofs(hogehoge.txt);
WriteToStream(ofs); //ファイルにも
ofs.close();

return 0;
}

後は,標準C++ライブラリにはstreamをイテレータとして使えるように
してくれるものもありますしね。


返信引用
monkey
 monkey
(@monkey)
ゲスト
結合: 20年前
投稿: 70
 

任意のクラスに対してストリーム出力用の operator << の定義し、
ストリームクラスのクラス階層を組み合わせて使ったときに最もメリットを感じます。
つまり、あるクラスに対してストリーム出力用の operator << が適切に定義されていれ
ば、
標準出力だけでなく、ファイルや文字列ストリームへの出力も << 演算子でできるとい
うこと。
書式指定は << の定義の中で1回だけ書けば良い。

class X{...};

std::ostream& operator << ( std::ostream& os, const X& x )
{
return os << ... ;
}

int main()
{
X x;
std::cout << x; // 標準出力へ出力

std::ofstream fout( file.txt );
fout << x; // ファイルへ出力

std::ostringstream oss;
oss << x; // 文字列ストリームへ出力
}


返信引用
こじま
 こじま
(@こじま)
ゲスト
結合: 22年前
投稿: 19
 

正直言って、あんまり便利でないですよね。。
iostreamの一番の問題点は、いわゆる「デザインとロジックの分離」ができないことか
な。
出力する書式をロジックで指定しないといけないのは結構つらいですよね。

型安全なprintfが欲しいということであれば、boost::formatとかになるんでしょうか。


返信引用
tib
 tib
(@tib)
ゲスト
結合: 22年前
投稿: 468
Topic starter  

私がC++初日に躓いてそのままにしていた問題に対し、様々なご意見ありがとうございます。

επιστημηさん:
私が最初に示した例よりはずっと見やすいですが、それでも私にはprintf()の方が見やす
いと感じてしまいます。
ユーザー定義型のoperator<<を定義できるというのがメリットとしてある事は解りました
が、複数パターンの出力方式が求められる場合に対応しづらくなりませんか?

PATIO さん:
ご指摘の通り、長年見慣れているからこそprintf()寄りになってしまうというのもあるで
しょう。確かに引数が多くなるとprintf()もフォーマット記述と引数の型が一致している
のか不安になりますし、保守性がいいとはとても言えませんね。

Kazukiさん、monkeyさん:
これまでの経験上あまりそういうパターンが殆どなかった(ファイルへの出力自体あまり
やらない)ので気付きませんでしたが、ファイルも文字列も同じように扱えるというのは
確かにメリットになりますね。

こじまさん:
boost::format !! これはいいですね。特に同じ意味のメッセージをいくつもの言語で
フォーマットしなくてはならない私には利用価値が高そうです。

皆さんのおかげで今まで避けていた領域に踏み込めそうです。ありがとうございました。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました