Cのフォーマット出力の手法について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
mak

Cのフォーマット出力の手法について

#1

投稿記事 by mak » 10年前

お世話になります。

質問
Cのフォーマット出力の手法について
C言語で計算したデータをテキスト出力したいのですが、
今printf系とboost::formatでなんとかできそうです。
が、やはりみなさんも出力するとしたらこうやるものでしょうか?
書き方がまどろっこしいというか
ほかの手法があれば、教えてください。

こうやるものでしょうか?

ほかの手法
が質問です。

目的はフォーマット化されたテキストデータ(string型)で、
printfの様なスッキリしたものかつ
srpintfはワンクッション
sprintf(strTmp,"・・・
str+=strTmp;がいたい。二行かかる。一行表示でもよいが一行当たりセミコロンが二つあり。
boost::formatは結構ひどい一行でかけるが。
str+=(boost::format("id・・・d3).str();

スマートな方法があればご伝授ください。


下記のような(ユニオンさまお借りします。)
http://www.unions.co.jp/service/structu ... les/06.pdf

のようなテキスト出力を考えています。
以下のコードは値はへんですが、コードを出します。

コード:

	double d1=100.5,d2=2000.251,d3=20.2515;

	printf("printfで直接出力する場合\n");
	for(int i=0;i<5;i++){
		d1=(i+5)*d1;
		d2=(i+5)*d2;
		d3=(i+5)*d3;
		printf("id=%2d  :  d1=%15.2f d2=%15.2f d3=%15.2f\n",i,d1,d2,d3);
	}

	printf("std::stringに文字列を貯める場合でsprintfの場合\n");
	d1=100.5;d2=2000.251;d3=20.2515;
	std::string str="";
	char strTmp[1024];
	for(int i=0;i<5;i++){
		d1=(i+5)*d1;
		d2=(i+5)*d2;
		d3=(i+5)*d3;
		sprintf(strTmp,"id=%2d  :  d1=%15.2f d2=%15.2f d3=%15.2f\n",i,d1,d2,d3);
		str+=strTmp;
	}
	printf(str.c_str());//str::stringをとりあえずコンソールへ書き出す。目的はstring型のデータ

	printf("std::stringに文字列を貯める場合でboostの場合\n");
	d1=100.5;d2=2000.251;d3=20.2515;
	for(int i=0;i<5;i++){
		d1=(i+5)*d1;
		d2=(i+5)*d2;
		d3=(i+5)*d3;
		str+=(boost::format("id=%2d  :  d1=%15.2f d2=%15.2f d3=%15.2f\n")% i% d1% d2% d3).str();
	}
	printf(str.c_str());//str::stringをとりあえずコンソールへ書き出す。目的はstring型のデータ

KORYUOH
記事: 44
登録日時: 12年前

Re: Cのフォーマット出力の手法について

#2

投稿記事 by KORYUOH » 10年前

iostream使っては?
ファイルでしたらfstreamで書き出せますが?
C言語を使うと自分の足を誤って撃ち抜いてしまうことがある。 C++を使えばそのような間違いを犯しにくくなる。しかし、やってしまったときには足全体が無くなる。

KORYUOH
記事: 44
登録日時: 12年前

Re: Cのフォーマット出力の手法について

#3

投稿記事 by KORYUOH » 10年前

若干補足します
fstreamとiomanip使えばフォーマット指定で書き出せます
C言語を使うと自分の足を誤って撃ち抜いてしまうことがある。 C++を使えばそのような間違いを犯しにくくなる。しかし、やってしまったときには足全体が無くなる。

mak

Re: Cのフォーマット出力の手法について

#4

投稿記事 by mak » 10年前

KORYUOH さんが書きました:iostream使っては?
ファイルでしたらfstreamで書き出せますが?
テキストがいいです。

iostreamちょっとしらべました。
直観的でないというか・・・

好みを言って何なんですが

std::string myString="";
myString +=Myprintf("id=%2d : d1=%15.2f d2=%15.2f d3=%15.2f\n",i,d1,d2,d3);
関数化できたらいいんですが、""の中身とd1 d2が変化するのでそんな技量がないというか。
sprintfに近いものって。

わかっていただけるでしょうか?

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: Cのフォーマット出力の手法について

#5

投稿記事 by ISLe » 10年前

もしかしてfprintfで済む話ですか?

mak

Re: Cのフォーマット出力の手法について

#6

投稿記事 by mak » 10年前

ISLe さんが書きました:もしかしてfprintfで済む話ですか?
ええと
文字列に\nをいれて複数行の文字列を一つの文字変数にいれたいだけです。シンプルに。
どうせファイル出力するなら・・・は今後のはなしです。

コード:

 
        sprintf(strTmp,"id=%2d  :  d1=%15.2f d2=%15.2f d3=%15.2f\n",i,d1,d2,d3);
        str+=strTmp;
 
だと二行いります。しかもstrTmp(char型 szか)もいります。
str+=でやりたい仕様です。シンプルに見やすく(ここで見やすいとは)
"id=%2d : d1=%15.2f d2=%15.2f d3=%15.2f\n",i,d1,d2,d3);
こんな感じであり、ほかに見やすいのがあればなおうれしい。



もっというとみなさんなら先にあげたpdf(txt)を出力する場合
どんなにしますか?も質問の一つです。

廻りに相談できる環境がないため、投稿しました。

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: Cのフォーマット出力の手法について

#7

投稿記事 by ISLe » 10年前

こういうことですかね。
最後のos.str()がご希望のものかと。

コード:

#include <sstream>
#include <iostream>
#include <boost/format.hpp>
int main()
{
	std::ostringstream os;

	double d1=100.5,d2=2000.251,d3=20.2515;
	for (int i=0;i<5;i++){
		d1=(i+5)*d1;
		d2=(i+5)*d2;
		d3=(i+5)*d3;
		os << boost::format("id=%2d  :  d1=%15.2f d2=%15.2f d3=%15.2f")% i% d1% d2% d3 << std::endl;
	}

	std::cout << os.str() << std::endl;
	return 0;
}

ISLe
記事: 2650
登録日時: 13年前
連絡を取る:

Re: Cのフォーマット出力の手法について

#8

投稿記事 by ISLe » 10年前

mak さんが書きました:もっというとみなさんなら先にあげたpdf(txt)を出力する場合
どんなにしますか?も質問の一つです。
業務向けにPDF出力するのなら帳票出力ツールを使うと思います。

mak

Re: Cのフォーマット出力の手法について

#9

投稿記事 by mak » 10年前

ISLe さんが書きました:こういうことですかね。
最後のos.str()がご希望のものかと。

コード:

#include <sstream>
#include <iostream>
#include <boost/format.hpp>
int main()
{
	std::ostringstream os;

	double d1=100.5,d2=2000.251,d3=20.2515;
	for (int i=0;i<5;i++){
		d1=(i+5)*d1;
		d2=(i+5)*d2;
		d3=(i+5)*d3;
		os << boost::format("id=%2d  :  d1=%15.2f d2=%15.2f d3=%15.2f")% i% d1% d2% d3 << std::endl;
	}

	std::cout << os.str() << std::endl;
	return 0;
}

申し訳ないです。私の仕様でいうと似たり寄ったりです。
ただ、str+=(boost::format("
boostの前の(がはずれて、きれいになりました。でも
os << ・・・<< std::endl;
をスマートと私の仕様でいえるか。。。言えます。。。。str+=(・・・).str();から
os << ・・・<< std::endl;
こっちに。。。微妙に抵抗あり。

で、話はこれで解決に至りそうです。
まだ、みなさんならどうかきます?はあります。

ここでトピが変更しそうですが、いかさせていただきます。
独自の関数は作れるのでしょうか?

コード:

 

std::string MyFormat(std::string strFormat,std::string strData){
	char szTmp[1024];
	sprintf(szTmp,strFormat,strData);

	return szTmp;
}

main{
	
	std::string strFormat="id=%2d  :  d1=%15.2f d2=%15.2f d3=%15.2f\n";
	std::string strData="i,d1,d2,d3";
	std::string strTXT="";
	strTXT+=MyFormat(strFormat,strData);
//もしくは
	strTXT+=MyFormat("id=%2d  :  d1=%15.2f d2=%15.2f d3=%15.2f\n","i,d1,d2,d3");
//第二引数が固定なら関数化は可能ですが、データの数はいろいろあり、方もいろいろ。
	
}
 

逆に何がしたいのかわからなくなりました。シンプルにが目的です。
わかりました。printfの返り値がstringになる関数がいい。

かずま

Re: Cのフォーマット出力の手法について

#10

投稿記事 by かずま » 10年前

mak さんが書きました: 独自の関数は作れるのでしょうか?

コード:

#include <cstdio>
#include <cstdarg>
#include <string>

std::string format(const char *fmt, ...)
{
    char buf[1024];
    va_list ap;
    va_start(ap, fmt);
    std::vsprintf(buf, fmt, ap);
    va_end(ap);
    return buf;
}

int main()
{
    double d1 = 100.5, d2 = 2000.251, d3 = 20.2515;
    std::string str;
    for(int i = 0; i < 5; i++) {
        d1 = (i+5) * d1;
        d2 = (i+5) * d2;
        d3 = (i+5) * d3;
        str += format("id=%2d  :  d1=%15.2f d2=%15.2f d3=%15.2f\n", i, d1, d2, d3);
    }
    std::fputs(str.c_str(), stdout);
    return 0;
}
vsnprintf を使ったほうが安全かもしれません。

mak

Re: Cのフォーマット出力の手法について

#11

投稿記事 by mak » 10年前

かずま さんが書きました:
mak さんが書きました: 独自の関数は作れるのでしょうか?

コード:

std::string format(const char *fmt, ...)
        str += format("id=%2d  :  d1=%15.2f d2=%15.2f d3=%15.2f\n", i, d1, d2, d3);
vsnprintf を使ったほうが安全かもしれません。
>vsnprintf を使ったほうが安全かもしれません。
はじめてその関数知りました。

教えていただいたコードはハードコードに似た感じが。
*fmt, ...)と, i, d1, d2, d3);に。
変数の型と数が固定されているような。です。

とにかく分かったことは、今やっていることがそんなもんなんだということがわかりました。
私の知らないスーパーコードがあるのかとの疑問から。

解決ボタンは押せないのでこのままにしておきます。

閉鎖

“C言語何でも質問掲示板” へ戻る