strcpy関数の戻り値を変数に保存したい

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ロコン

strcpy関数の戻り値を変数に保存したい

#1

投稿記事 by ロコン » 7年前

以下のようなコードを実行してstrcpyの結果をprintfで表示させたいのですが想定とは異なる結果となりました。
想定
タイトル
サブタイトル
結果
END
END
という風に表示されました
何がいけなかったのでしょうか?

コード:

#pragma warning(disable:4996)
#include <stdio.h>
#include <string.h>

#define MAX 2048
int main(void) {
	FILE *fp;
	char buf[500];// [MAX];
	char *title, *subtitle;
	if ((fp = fopen("test.txt", "r")) != NULL) {
		while (fgets(buf, MAX, fp) != NULL) {
			if (strstr(buf,"#END") != NULL) break;//STARTでヘッダ終了
			if ((strstr(buf, "TITLE:") != NULL) && (strstr(buf, "SUBTITLE:") == NULL)) {//タイトル
				title = strcpy(buf + 1, buf + 6);
				continue;
			}
			if ((strstr(buf, "SUBTITLE:") != NULL)) {
				subtitle = strcpy(buf + 1, buf + 9);
				continue;
			}
		}
	}
	printf("%s", title);
	printf("%s", subtitle);
	while(1){}
	return 0;
}
test.txt

コード:

TITLE:タイトル
SUBTITLE:サブタイトル
#END

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: strcpy関数の戻り値を変数に保存したい

#2

投稿記事 by みけCAT » 7年前

まず、一般的な文字コードでは全角カタカナは2バイト以上で表されるので、重なった領域間でのstrcpyをすることになり、未定義動作になります。
次に、titleやsubtitleにはbuf[1]を指すポインタが格納されています。(未定義動作なので何が起こってもおかしくないですが、strcpyの通常の動作およびENDが出力されていることからこう予想できます)
bufの中身はfgetsによって上書きされるので、strcpyの戻り値を代入した時の文字列をそのまま保持することはできません。
最後に、fopenしたのにfcloseしていないこと、そしてtitleやsubtitleがtest.txtの中身によっては不定のままprintfに渡されてしまうのもよくないように思えます。
ロコン さんが書きました:何がいけなかったのでしょうか?
「以下のようなコードを実行してstrcpyの結果をprintfで表示させたい」「strcpy関数の戻り値を変数に保存したい」と考えたのがいけなかったのでしょう。
想定の結果を得るには、「strcpy関数の戻り値を変数に保存する」のではなく、「mallocなどで確保した領域へのポインタを変数に保存し、そこにstrcpyする」のがいいでしょう。
文字列を格納する領域は、少なくとも文字列の長さ(strlenで得られる)+1(最後のナル文字の分)バイト必要です。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

ロコン

Re: strcpy関数の戻り値を変数に保存したい

#3

投稿記事 by ロコン » 7年前

ありがとうございます!!
うまくいきました!

返信

“C言語何でも質問掲示板” へ戻る