Borland C++ Builder 5 を使っています。
StringGridの内容をクリップボードにCOPYするプログラムを作っています。
Excelに貼り付けるのが目的なので、Tab区切りのデータにしています。
下に示したソースで実現できましたが、非常に遅いのです。
100行とか200行ならアッという間なのですが、2,000行、3,000行となるとかなり待たされます。
時間を食っているのは(2)の部分のようです。
もう少しスマートに、短時間でCOPYしたいのですが、方法はないものでしょうか?
◆ソースの解説
StringGridの21列分を、行数だけクリップボードにCOPYします。
(1)
StringGridの各行、各列をLOOPしてセルに格納されている文字列長の合計を求めます。
Tab区切りにするため、各セルごと1バイト加算します。
また、各行ごと改行を入れるため、これも1バイト加算します。
(2)
合計容量が計算できたら、メモリーを動的確保し、もう一度LOOPをしながら、文字列をCOPYします。
セルごとにTab、行ごとに改行も追加します。
(3)
最後にクリップボードをクリアしてCOPYします。
int cnt = StringGrid1->RowCount;
int size = 0;
//StringGridのサイズ(文字長)をカウントする ------ (1)
for(i=0;i<cnt;i++){
for(k=0;k<21;k++){
size += strlen(StringGrid1->Cells[k][i].c_str()) + 1;
}
size++;
}
//メモリーを確保して、StringGridをCOPYする -------- (2)
cb = new char[size];
strcpy(cb,"");
for(i=0;i<cnt;i++){
for(k=0;k<21;k++){
strcat(cb,StringGrid1->Cells[k][i].c_str());
strcat(cb,"\t"); //Tab区切りの文字列にする
}
strcat(cb,"\n");
}
Clipboard()->Clear(); // -------- (3)
Clipboard()->AsText = cb;
なお、サイズがintに収まるかというチェックとか、メモリーの解放をする、といったことも必要ですが、記述を省略しました。
No.1ベストアンサー
- 回答日時:
strcatで毎回連結しているようですが、質問内容のソースコードでは毎回'\0'を探し出して、その後に文字列を連結しているため処理効率が落ちてしまいます。
以下のようにしてはどうでしょう。
追加宣言
int mcnt,mlp;
(2)の部分のソースコード
cb = new char[size];
cb[0] = '\0';
mcnt = 0;
for(i=0;i<cnt;i++){
for(k=0;k<21;k++){
for(mlp=0;mlp<strlen(StringGrid1->Cells[k][i].c_str());mlp++){
cb[mcnt] = StringGrid1->Cells[k][i].c_str()[mlp];
mcnt++;
}
//Tab区切りの文字列にする
cb[mcnt] = '\t';
mcnt++;
}
//行ごとに改行する。
cb[mcnt] = '\n';
mcnt++;
}
//最後に'\0'を付加。
cb[mcnt] = '\0';
mcnt++;
申し訳ありませんが、試してはいません。
hiro_knighさん、ありがとうございました。
>strcatで毎回連結しているようですが、質問内容のソースコードでは毎回'\0'を探し出して、その後に文字列を連結しているため処理効率が落ちてしまいます
どうもそのようです。
試しに、次のようなstrcatのテストプログラムを作ってみました。
char Tmem[400001]="";
char moji[]="0123456789";
int i;
for(i=0;i<20000;i++) strcat(Tmem,moji);
20,000回のLOOPで、約3秒かかりますが、倍の40,000回のLOOPでは、11秒もかかります。(ストップウォッチによる手動計測)
回数を倍にしただけなのに、時間は4倍弱掛かっています。
'\0'を探し出すのに時間が掛かっているようです。
アドバイスを参考に、kのLOOPを次のようにしました。
len = strlen(StringGrid1->Cells[k][i].c_str());
strncpy(&cb[st],StringGrid1->Cells[k][i].c_str(),len);
cb[st + len] = '\t';
st = st + len +1;
その結果、手動計測では測定不可能なほど早くなりました。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・「I love you」 をかっこよく翻訳してみてください
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・昔のあなたへのアドバイス
- ・かっこよく答えてください!!
- ・あなたが好きな本屋さんを教えてください
- ・スタッフと宿泊客が全員斜め上を行くホテルのレビュー
- ・【大喜利】【投稿~8/27】 こんなガソリンスタンド二度と来るか!なぜそう思った?
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・【お題】動物のキャッチフレーズ
- ・【お題】甲子園での思い出の残し方
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・「それ、メッセージ花火でわざわざ伝えること?」
- ・自分用のお土産
- ・人生で一番お金がなかったとき
- ・一番好きなみそ汁の具材は?
- ・泣きながら食べたご飯の思い出
- ・ちょっと先の未来クイズ第1問
- ・ゴリラ向け動画サイト「ウホウホ動画」にありがちなこと
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CSVファイルの中で、「 , 」カ...
-
EXCELからCSVにすると余計なカ...
-
マクロを使ってフォルダー内に...
-
エクセルで数値を全角文字(カ...
-
CSVの定義
-
カンマ区切りの数字をCSVフ...
-
データにカンマが入ったCSVデー...
-
StringGridの内容をクリップボ...
-
何故、日本は未だに数字を3桁...
-
VB2005のTextBoxでカン...
-
【VBA】エクセルで値のみクリッ...
-
エクセルにペーストする際にカ...
-
数字が全角、コンマなし
-
パス区切りの文字について
-
海外のケータイ(GSM携帯)はハ...
-
WORDで改ページすると時々グレ...
-
[.NET2.0] メニューに区切り線
-
C#で、テキストボックスの入力...
-
[VBA][Excel]クリップボードか...
-
PHP カンマをエスケープしたい...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CSVファイルの中で、「 , 」カ...
-
エクセルで数値を全角文字(カ...
-
EXCELからCSVにすると余計なカ...
-
マクロを使ってフォルダー内に...
-
CSVの定義
-
カンマ区切りの数字をCSVフ...
-
WORDで改ページすると時々グレ...
-
データにカンマが入ったCSVデー...
-
[VBA][Excel]クリップボードか...
-
カンマ区切り
-
VB2005のTextBoxでカン...
-
3桁ごと?4桁ごと?コンマの...
-
数字が全角、コンマなし
-
何故、日本は未だに数字を3桁...
-
PHP カンマをエスケープしたい...
-
C#で、テキストボックスの入力...
-
ひとつの命令を複数行に記述
-
VBAでtxtファイルを読み込む際...
-
JPY ¥1,500.00は日本円でお幾ら?
-
Excelについて質問です。 セル...
おすすめ情報