
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で質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語 プログラムのエラー 1 2023/02/11 20:31
- C言語・C++・C# 宣言する関数の形が決まっている状態で、 str1とstr2の文字列をこの順に引っ付けてstrに保存し 2 2022/05/30 18:21
- C言語・C++・C# C#テキストボックスの文字を配列にいれてその後表示する 4 2022/07/17 04:47
- C言語・C++・C# str[j++]の意味 2 2022/08/30 16:20
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
- C言語・C++・C# c言語配列の結合についてです。 なぜうまくいかないのでしょうか。 #include <stdio.h 4 2022/05/30 22:42
- Visual Basic(VBA) 【困っています2】VBA 追加処理の記述を教えてください。 2 2022/08/26 11:42
- Visual Basic(VBA) 改行ごとに行を追加し、数量を分割 4 2023/07/11 16:39
- Visual Basic(VBA) 【前回の続き続きです、ご教示ください】VBAの記述方法がわかりません。 2 2022/08/24 20:49
- Visual Basic(VBA) エクセルVBAコピー 2 2022/06/08 21:45
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Excelについて質問です。 セル...
-
CSVファイルの中で、「 , 」カ...
-
CSVの定義
-
2進数など
-
VBAでtxtファイルを読み込む際...
-
エクセルで数値を全角文字(カ...
-
エクセルで電話番号を取り出す...
-
特定の文字を削除したい
-
EXCELからCSVにすると余計なカ...
-
住宅にカナを入力する際に丁目...
-
文字コードの%E3%80%とは何です...
-
全角/半角キーをSendkeys関数で...
-
プログラミングでは、半角括弧...
-
16進数の文字列を文章に変える
-
携帯サイトは半角カナが当たり...
-
Excelの中に全角ひらがな、漢字...
-
全角英数字の必要性が理解できない
-
正規表現の質問です。
-
エクセル:セル「D列」に「○○○...
-
いまスマホからカードの申込み...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CSVファイルの中で、「 , 」カ...
-
エクセルで数値を全角文字(カ...
-
マクロを使ってフォルダー内に...
-
EXCELからCSVにすると余計なカ...
-
Excelについて質問です。 セル...
-
CSVの定義
-
[VBA][Excel]クリップボードか...
-
WORDで改ページすると時々グレ...
-
カンマ区切りの数字をCSVフ...
-
C#で、テキストボックスの入力...
-
データにカンマが入ったCSVデー...
-
VBAでtxtファイルを読み込む際...
-
カンマ区切り
-
VB2005のTextBoxでカン...
-
メモ帳からエクセルにセル区切...
-
JPY ¥1,500.00は日本円でお幾ら?
-
テキストファイルからReadLine...
-
カンマ区切りでないテキストをc...
-
エクセルにペーストする際にカ...
-
パス区切りの文字について
おすすめ情報