エディットボックスからcharのバッファに格納 – プログラミング – Home

エディットボックスからcharのバッフ...
 
通知
すべてクリア

[解決済] エディットボックスからcharのバッファに格納


roccy
 roccy
(@roccy)
ゲスト
結合: 24年前
投稿: 82
Topic starter  

環境は、VC++でMFCでやってます。

・エディットボックスから取得した文字をcharのバッファに
 入れたいのですが、次の方法でやっているとなぜか落ちるように
 なりました。
 エディットボックスから取得した文字が10文字より大きいなら
 10文字にしてそれをバッファに入れます。文字列の終端コードは
 10文字の場合は入らなくてもいいです。
 10文字未満の場合は、残りを0で埋めなければなりません。

char CharArray[10];
CString Str(");

GetDlgItem( IDC_EDIT1 )->GetWindowText( Str );

// 10文字にカット
if(Str.GetLength(10) >= 10){
Str = Str.Left( 10 );
}
// charのバッファに格納
memcpy( CharArray, Str.GetBuffer(0), sizeof(char) * 10);

・今度は、逆にcharのバッファに入っている文字をCStringにいれて
 エディットボックスに出力したいのですが、同様に落ちるように
 なりました。
 charのバッファには、終端コードが含まれていない場合もあります。
 charのバッファには、10文字未満の文字列が入っている場合は、
 残りのバッファは、0で埋められています。

CString Msg;
Msg = CharArray;
Msg = Msg.Left( 10 );
GetDlgItem( IDC_EDIT )->SetWindowText( Msg );

これらのソースに問題があるのでしょうか?
もっと何か効果的なやり方があるように思えるのですが、
うまく考えつかなかったので、どなたかご存知の方教えてください。


引用未解決
トピックタグ
Bun
 Bun
(@Bun)
ゲスト
結合: 24年前
投稿: 761
 

>char CharArray[10];
>CString Str(");
>GetDlgItem( IDC_EDIT1 )->GetWindowText( Str );
>// 10文字にカット
>if(Str.GetLength(10) >= 10){
> Str = Str.Left( 10 );
>}
>// charのバッファに格納
>memcpy( CharArray, Str.GetBuffer(0), sizeof(char) * 10);

あんまし、自信なしですが

1. CharArray[10+1];
ZeroMemory(CharArrya, sizeof(CharArray)); // とでもしておきますか。

2. GetLength()ですか。(引数なし)

3. 0ぢゃなくて、GetBuffer(10)ですか。

4. ReleaseBuffer()してますか?

>もっと何か効果的なやり方があるように思えるのですが、
wsprintf(CharArray, %s, Str);
のほうが楽チンかな。

#書き込み側は問題ないんぢゃない。(^^;


返信引用
K
 K
(@K)
ゲスト
結合: 23年前
投稿: 98
 

void CPRG1Dlg::OnButton1()
{
// TODO: この位置にコントロール通知ハンドラ用のコードを追加してください
char CharArray[10] ;
CString Str(") ;

GetDlgItem (IDC_EDIT1)->GetWindowText (Str) ;

// 10文字にカット
// if(Str.GetLength(10) >= 10){
if(Str.GetLength () > 10) {
Str = Str.Left (10) ;
}
// charのバッファに格納
// memcpy ( CharArray, Str.GetBuffer (0), sizeof (char) * 10) ;
memset (CharArray, 0x00, sizeof (CharArray)) ;
// charのバッファには、10文字未満の文字列が入っている場合は、
// 残りのバッファは、0で埋められています。
strcpy (CharArray, Str) ;

MessageBox (CharArray) ;

//・今度は、逆にcharのバッファに入っている文字をCStringにいれて
// エディットボックスに出力したいのですが、同様に落ちるように
// なりました。
Str.Empty () ;
Str.Insert (0, CharArray) ;
GetDlgItem (IDC_EDIT1)->SetWindowText (Str) ;
}


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

> // charのバッファに格納
> memcpy( CharArray, Str.GetBuffer(0), sizeof(char) * 10);

Strの長さが10文字未満の場合、Strのバッファは10バイトより
短い可能性があります。
その場合、Strのバッファからはみ出た部分をアクセスしようとして、
場合によっては落ちるでしょう。

strncpyのヘルプを見てみると、まさに要望どおりの動作をする
関数であることが分かります。よって、以下の2行でOKです。

GetDlgItem( IDC_EDIT1 )->GetWindowText( Str );
strncpy(CharArray, Str, sizeof(CharArray));

> CString Msg;
> Msg = CharArray;

CStringへ文字配列を代入する時には、代入される文字配列の終端記号までを
コピーしようとします。CharArrayに10文字いっぱい入っていて終端記号がない場合、
CharArrayバッファからはみ出た部分をアクセスしようとして、
場合によっては落ちるでしょう。

CStringのコンストラクタには、文字列の長さを指定できるバージョンがあります。
よって、以下の2行で可能です。

CString Msg(CharArray, 10);
GetDlgItem( IDC_EDIT )->SetWindowText( Msg );


返信引用
YuO
 YuO
(@YuO)
ゲスト
結合: 24年前
投稿: 252
 

>エディットボックスから取得した文字が10文字より大きいなら
>10文字にしてそれをバッファに入れます。文字列の終端コードは
>10文字の場合は入らなくてもいいです。
>10文字未満の場合は、残りを0で埋めなければなりません。

char CharArray[10] = {0}; // とりあえず0クリア
char buffer[11]; // NULを含む為,11Bytes確保

int r = GetDlgItem(IDC_EDIT1)->GetWindowText(buffer, 11); // 最大10Bytes読む。
memcpy(CharArray, buffer, r); // 複製
終端コードを常にいれて良いなら,

char CharArray[10];

int r = GetDlgItem(IDC_EDIT1)->GetWindowText(CharArray, 10);
memset(CharArray + r, 0, 10 - r); // 0クリア


返信引用
roccy
 roccy
(@roccy)
ゲスト
結合: 24年前
投稿: 82
Topic starter  

Bunさん、Kさん、dairygoodsさん、YuOさん、ありがとうございました。
普段、MFCばかり使ってポインタの意識が薄れていました。

>Bunさん、Kさん
ご指摘のとおり、
GetLength()でした。これは、記述ミスです。

>dairygoodsさん
感動しました。いろいろ考えたのにこんなに簡単にやってのけるとは
この方法でやってみます。
・文字列取得時
GetDlgItem( IDC_EDIT1 )->GetWindowText( Str );
strncpy(CharArray, Str, sizeof(CharArray));
(理由)
取得した文字列が10文字未満のとき0埋めをしてくれ、
10文字以上のとき10文字分のサイズを取得してくれる

・文字列出力時
CString Msg(CharArray, 10);
GetDlgItem( IDC_EDIT )->SetWindowText( Msg );
(理由)
バッファに格納されている10文字分をCStringに入れてくれる

ただ、気になる点が1つ
CString Msg(CharArray, 10);
charのバッファの最後に終端コードが入ってなくても
大丈夫なのでしょうか?
コンストラクタで自動的に入れてくれるのでしょうか?


返信引用
dairygoods
 dairygoods
(@dairygoods)
ゲスト
結合: 23年前
投稿: 1421
 

> ただ、気になる点が1つ
> CString Msg(CharArray, 10);
> charのバッファの最後に終端コードが入ってなくても
> 大丈夫なのでしょうか?

自動的に入ります。

気になる点があったら、自分でプログラムを作って確認したほうが
早くて確実ですよ(^^;


返信引用
roccy
 roccy
(@roccy)
ゲスト
結合: 24年前
投稿: 82
Topic starter  

ありがとうございました。
自分でも確認はしたのですが、不安なもので...
でも解決してよかったです。


返信引用

返信する

投稿者名

投稿者メールアドレス

タイトル *

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