STLでの文字列作成について – プログラミング – Home

STLでの文字列作成について
 
通知
すべてクリア

[解決済] STLでの文字列作成について


sunyopu
 sunyopu
(@sunyopu)
ゲスト
結合: 23年前
投稿: 68
Topic starter  

現在携わっている仕事(環境:WinXP,VC++6.0)で、
あるプログラムを作成しているのですが、
移植性を高めるためにMFCを使用しないという
ルールになっています。

普段、文字列操作には
MFC の CString を使用しているのですが、
今回は STL の string を使っています。

大半は不自由ないのですが、
数値を文字列にする場合、以下のような手法しか
分からず多少面倒です。

char caWork[100];
sprintf(caWork, %d %s … , 11111, aaaa, …);
string strWork = caWork;

CString の場合は、CString::Format() で
バッファサイズを意識することもなく簡潔に記述できるのですが、
string でも似たようなことができないものでしょうか?

もう少しすっきりコーディングしたいな思っています。
何かいい手法があったらお教え願いたいです。


引用未解決
トピックタグ
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

#include <sstream>
#include <string>

.....

std::ostringstream oss;
oss << 11111 << << aaaa;
std::string strWork = oss.str();

こんな感じ?


返信引用
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

> 数値を文字列にする場合、

環境がゆるすなら boost を導入するとか、

std::string strWork = boost::lexical_cast<std::string>(11111);

このイメージで stringstream のラッパを自作するのもアリでしょうか。


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

lexical_cast の実装それ自体、 stringstream のラッパです ^^;


返信引用
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

>επιστημηさん

> lexical_cast の実装それ自体、 stringstream のラッパです ^^;

御意。ヘッダ内も読んでますからこの事自体は知ってますが、
ただ「実績のない外のライブラリは使っちゃいかんっ」って
現場もあったりするので、わざわざ車輪の再発明が必要かもと
思いまして>自作
# 実は経験者(^ ^;


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

あるいはsprintfをラップして:

std::string form(const char* format, ...)

をこしらえますか。


返信引用
sunyopu
 sunyopu
(@sunyopu)
ゲスト
結合: 23年前
投稿: 68
Topic starter  

みなさん、
ご返事ありがとうございます。

> std::ostringstream oss;
> oss << 11111 << << aaaa;
> std::string strWork = oss.str();

勉強になります。
これなら簡潔になりますね。

欲をいえば、
sprintfとかの書式指定(%05dとか%3.2f)が
使えればいいのですが...

> 環境がゆるすなら boost を導入するとか、

自分自身、boostの概要くらいしか知らず、
仕事での納期もあるため次の機会にしたいです。
個人的には大いに興味があります。

> あるいはsprintfをラップして:

そういう方法もありますね。
バッファサイズを意識しないで使えるように
実装できれば完璧だと思います。
(難しそうではありますが...)

日ごろはCStringを何気なく使っていますが、
使えないと便利さが再認識させられます。

状況に応じて色々やってみようと思います。


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

> 欲をいえば、
> sprintfとかの書式指定(%05dとか%3.2f)が
> 使えればいいのですが...

書式指定にはマニピュレータと言われるものを使います。

// sample
#include <sstream>
#include <iomanip>
#include <string>
#include <iostream>

int main()
{
using namespace std;

int n = 123;
double r = 1.2;

ostringstream oss;
oss << setw( 5 ) << setfill( '0' ) << n <<
<< setw( 3 ) << fixed << setprecision( 2 ) << r;

string s = oss.str();

cout << s << endl;
}


返信引用
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

> バッファサイズを意識しないで使えるように
> 実装できれば完璧だと思います。

とりあえずVC.NET2003だとこんな感じでしょうか。

std::string
form(const char* const format, ...)
{
va_list arguments;
std::vector<char> buffer;

assert(format);
va_start(arguments, format);
try{
int length = _vscprintf(format, arguments) + 1;
if(length < 1) throw std::runtime_error(format);
buffer.resize(length);
int result = vsprintf(&buffer.front(), format, arguments);
if(result < 0) throw std::runtime_error(format);
buffer[length-1] = '\0'; // 保険
}
catch(...)
{
va_end(arguments);
throw;
}
va_end(arguments);
return &buffer.front();
}

残念ながら VC6 だとバッファ長を取得する _vscprintf が
使えないのでちょっと面倒かも。vector::front も使えなかった....。

# なお、上の例だと vector が連続領域に確保されるSTLの実装系に
# 依存しますので、boost::scoped_array あたりにした方がいいかも。


返信引用
Ban
 Ban
(@ban)
Prominent Member
結合: 5年前
投稿: 776
 

boost は読んでていためになりますし、けっこう面白いです。
# いや、便利なものも多数ありますよ、ちゃんと(^ ^;

> sprintfとかの書式指定(%05dとか%3.2f)が
boost::basic_format なら、
C++ のマニピュレータ指定を C の printf 風に記述できたりします。
# %演算子のオーヴァロードで実装されてます。

実際に使うのかと言われたらまずいらないと思いますが....
オーヴァロードのハックの例でしょうか。(^ ^;


返信引用
sunyopu
 sunyopu
(@sunyopu)
ゲスト
結合: 23年前
投稿: 68
Topic starter  

Ban さん、
色々お教えいただきありがとうございます。
大変勉強になります。

> 書式指定にはマニピュレータと言われるものを使います。

これを使用すれば書式指定ができるのですね。
ぜひ使用したいと思います。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

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