Windows APIでプログラミングをしています。
Windows APIでプログラミングをしています。
char*型の文字列を表示させようと、このように記述しました。
const char * y;
y=f();
SelectObject(hdc , hFont);
SetBkColor(hdc , RGB(255 , 255 , 255));
wsprintf( str, "名前は、%s", y );
TextOut(hdc , 300, 20, str, lstrlen(str));
すると、表示できたのはいいのですが、
タイトルバーをクリックしてウィンドウを広げたり、別のウィンドウを一番前に持ってきて、
その後、そのウィンドウを出したりすると、エラーが出て、強制終了になってしまします。
何か問題はありますか?
ちなみに、strの宣言はこのようになっております。
static TCHAR str[64];
あとですが、
wsprintf( str, "名前は、%s", y );
この部分のyを&yに変えると、エラーは起こりませんが、
変な文字が表示されてしまいます。
ウィンドウを少し操作すると、その文字がまた変な文字に変わります。
何が原因でしょうか。
No.1
- 回答日時:
変数yに対して constを宣言していますが本当に const宣言が必要なのでしょうか
関数fの戻り値を代入していますが 毎回実行する必要があるのでしょうか
const宣言で変更できないchar型のポインタを使うならこのイベントの関数の外で
const char *y = f();
といった宣言をしてみてください
もし fが何かのクラスのメンバー関数ならstatic属性を付加しないといけないでしょう
一般的な変数なら
char *y;
といった宣言のほうが良いように思いますよ
yを &yに変更してしまうとぜんぜん違う意味になります
yのままなら 文字列を示すポインタ
&yにすると このポインタが保存されているメモリのアドレス
となって wsprintfの引数として %sを表すには不適格です
No.2
- 回答日時:
y=f();
このf( )がわからないと答えられないでしょう
f( )でmallocしてそのポインタを返しているのでしょうか
それならy の free( )はどこでしているのでしょうか
mallocしたらfreeしましょう
fの内容は次のようになっております。
free(y);
をどこにおいても同じ結果になります。
const char * f(){
FILE *fp;
char chars[1000]; /* 読み込む文字 */
char temp[1000];
int count, i,read,j,k,l=0,flag;
char tempone[1000],temptwo[1000],tempthree[1000],tempfour[1000],tempfive[1000];
char ch = ' ';
char *x;
fp = fopen("mux2.v", "r");
if (fp == NULL){
printf("sample.txt を開けませんでした。\n");
return EXIT_FAILURE;
}
count = 0;
/* 読み込み */
while ((read = fgetc(fp)) != EOF)
{
chars[count] = read;
count++;
}
flag = 1 ;
for( i = 0 ; i <= 1000 ; i++ ){
if( chars[i] == 'm' && chars[i+1] == 'o' && chars[i+2] == 'd' && chars[i+3] == 'u' && chars[ i+4] =='l' && chars[i +5]=='e' && chars[i + 6] ==' '){
for( j = 0 ; j <= 6 ; j++ ){
printf("%c",chars[i + j]);
}
for( k = 7 ; k <= 20 ; k++ ){
if( chars[i + k] != '(' ){
temp[i + k] = chars[i + k];
printf("%c",chars[i + k]);
}else{
temp[i+k] = '\0';
}
}
for( k = 7 ; k <= 20 ; k++ ){
if( chars[i + k ] != '(' ){
printf("%c",temp[i + k ]);
}else{
break;
}
}
printf("\t");
if( flag == 1 ){
for( k = 7 ; k <= 20 ; k++ ){
tempone[ l ] = temp[ i + k ];
l = l + 1;
}
}
if( flag == 2 ){
for( k = 7 ; k <= 20 ; k++ ){
temptwo[ l ] = temp[i + k ];
l = l + 1;
}
}
if( flag == 3 ){
for( k = 7 ; k <= 20 ; k++ ){
tempthree[ l ] = temp[i + k ];
l = l + 1;
}
}
if( chars[i] == EOF ){
break;
}
flag = flag + 1;
l = 0;
}
}
x = malloc(strlen(tempone) + 1);
if(x == NULL) { exit(1); }
strncpy(x, tempone, strlen(tempone));
return x;
}
No.4ベストアンサー
- 回答日時:
★アドバイス
>表示はされますが、その後、ウィンドウを閉じたりすると問題が発生してしまします。
↑
恐らくは次の1行が原因です。
>strncpy(x, tempone, strlen(tempone));
↑
この1行は『tempone』という文字列を『x』にコピーしていますが
文字列の末尾を表す '\0' は何処で書き込みました。
書き込んでいませんよね。
これが原因です。
改善策:
・(1)malloc() ではなくて calloc() 関数を使って確保する。
(2)『tempone[ strlen(tempone) ] = '\0';』の1行を追加する。
単純にこれだけです。
その他:
・fopen() したのに fclose() していません。
必ず f() 関数を抜ける前に fclose() して下さい。
修正箇所は
(1)最後の『exit(1);』する前に fclose() します。
(2)最後の『return x;』する前に fclose() します。
※(1)は exit() して終了しているので特に fclose() 記述しなくても良いです。
※あと Windows のプロシージャ内なら ExitProcess() を記述したほうが良いです。
でも exit() 関数は API の ExitProcess() を内部で呼んでいそうだね。
・それからソースを見ての感想として次の1行は strncmp() 関数を使ったらどうかな。
>if( chars[i] == 'm' && chars[i+1] == 'o' && chars[i+2] == 'd' && chars[i+3] == 'u' && chars[ i+4] =='l' && chars[i +5]=='e' && chars[i + 6] ==' '){
↑
この1行を『if ( !strncmp(&chars[i],"module ",7) ){』とします。
この方が分かりやすいですよ。
・あと『読み込み』時に chars[] 配列の容量をチェックして下さい。
『mux2.v』ファイルが 1000 バイト以上だとメモリを破壊してしまいます。注意!
・以上。少々おせっかいな事を3つ『その他』で助言しておく。
No.6
- 回答日時:
>メッセージボックスで実行してみましても同じ結果になります。
>表示はされますが、その後、ウィンドウを閉じたりすると問題が発生してしまします。
表示できるかではなく、どのステップまで実行されているのかを
確かめてください。
どんなコードを書いているのか少し判りづらいですが、
ウィンドウサイズや、フォーカスの変化による
無効領域の発生が原因だと思われます。
無効領域が発生した場合、通常はプロシージャの中で
WM_PAINTをハンドルして再描画を行います。
参考URL:http://www.geocities.jp/ky_webid/win32c/014.html
No.7
- 回答日時:
問題は解決されたようですが、一つ気になった点を上げます。
関数f()の戻り値ですが、ファイルのオープンに失敗した場合にEXIT_FAILUREを返していますが、呼び出し側でエラーチェックをしていないですね。
f()の呼び出し後、wsprintf( str, "名前は、%s", y ); が実行されているので、ファイルがオープン出来なかった場合はここで落ちる可能性が高いです。
>fclose(fp);
>を追加後、問題解決しました。
との事なので、おそらくウインドウの捜査をして2回目の実行で開きっぱなしのファイルを重複オープンしようとしてエラーになっていたのでしょう。
ファイルのクローズも必要ですが、各所でのエラーチェックも重要です。
また、char*型にEXIT_FAILUREを返すのもあまり良くないです。
この場合はNULLを返すようにして、呼び出し側では以下のようにします。
char* y = f();
if(y){
/* 正常だった時の処理 */
SelectObject(hdc , hFont);
SetBkColor(hdc , RGB(255 , 255 , 255));
wsprintf( str, "名前は、%s", y );
TextOut(hdc , 300, 20, str, lstrlen(str));
}
EXIT_FAILUREは規格上は0以外のなんらかの整数値のようなので、有効なポインタの判別には使えません。
この回答への補足
次のステップにて、エラーが出てしまったので、
EXIT_FAILUREを0に直したところ、エラーは出なくなりました。
どうもありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
関数内で設定したポインタ値に...
-
メモリ関連のエラーを取り除く...
-
C++Builder 2009 テキスト...
-
strcat関数を自作したいです
-
別ファイルの内容を検索したい...
-
char*を初期化したいのですが
-
ASCIIコードへの変換方法
-
char型にint型の数値を代入する。
-
ポインタで詰まりました;
-
C++のnewで確保したメモリーの...
-
VB.NETでファイル名順にファイ...
-
C言語 構造体の中に共用体を定...
-
関数から配列を返すには?
-
C言語のポインタに直接アドレス...
-
malloc呼び出し時のセグメンテ...
-
C言語 配列の長さの上限
-
構造体配列のソート
-
C言語の文字列?処理 strcpyやl...
-
C#で構造体の配列を持った構造...
-
2次元配列を戻り値とする関数?
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
char*を初期化したいのですが
-
C言語のintとcharの違いってな...
-
CStringからchar*への型変換に...
-
C言語にて構造体のメンバがNULL...
-
fstream型オブジェクトを関数の...
-
小数点入りの文字列をfloat型に...
-
char型にint型の数値を代入する。
-
const char* s1とただのchar s1...
-
new charとnew char[N]の違いは?
-
動的メモリの初期化方法について。
-
エクセルのMID関数は、C言語では?
-
C言語 strstrの実装
-
SetWindowTextについて。
-
char 文字列型 の表現範囲が-12...
-
文字列の途中から途中までを抽出
-
2次元配列の文字"列"の初期化方法
-
DWORDとcharの変換
-
C++17で、unsigned char * 配列...
-
C言語の文字リテラル中の16進文...
-
strcat関数を自作したいです
おすすめ情報