文字列の操作がうまくいかない(C++)

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Jimmy
記事: 9
登録日時: 7年前

文字列の操作がうまくいかない(C++)

#1

投稿記事 by Jimmy » 6年前

自作の関数char* getBack3(char*)というのを作りました。
この関数は「与えられた文字列の後ろ3文字を返す」という仕様です。 例: "abcd" → "bcd"
ですが、文字列やポインタなどの概念をしっかりと把握していないせいか、自分の思うように動きません。

コード:

#include<cstdio>
#include<cstring>

char* getBack3(char *);

int main(){
	char *back3 = getBack3("abcd");
	printf("main()内に返ってきた>> ");
	puts(back3);

	printf("\n");

	getchar();
}

// 後ろ三文字を入手(strは3文字以上あることが保証されている)
char* getBack3(char* str){
	char word[4];
	int j = 0;
	for(int i = strlen(str)-3; str[i] != '\0'; i++, j++){
		word[j] = str[i];
	}
	word[j] = '\0';

	printf("getBack3()内>>	");
	puts(word);
	return word;
}
getBack3("abcd")と与えるので、戻り値は"bcd"がなることを期待しています。
関数内では正常に"bcd"を"abcd"から取得しているようですが、main()に戻ってくると以下のように文字化けします。

[tab=30]getBack3()内>> bcd
[tab=30]main()内に返ってきた>> ア㍾

原因はわかりません。
どなたかお助けお願いします。

【15時46分追記】
上記のコードの12行目に

コード:

char back3_2[4];
strcpy(back3_2, getBack3("abcd"));
printf("main()内に返ってきた>> ");
puts(back3_2);
追加して実行すると、この追加したコードは思った通りの動作を実現してくれます。
ですが、strcpy()を使わない方法を教えて下さい。
最後に編集したユーザー Jimmy on 2013年8月01日(木) 15:49 [ 編集 1 回目 ]

KORYUOH
記事: 44
登録日時: 7年前

Re: 文字列の操作がうまくいかない(C++)

#2

投稿記事 by KORYUOH » 6年前

単純にwordがローカルスコープなのと
返しているのがアドレスなので変なアドレスが返ってきているパターンだと思うのでアドレスで出力してみてください。

一番いいのはchar*ではなくC++なのだからstd::stringを使うことです。
C言語を使うと自分の足を誤って撃ち抜いてしまうことがある。 C++を使えばそのような間違いを犯しにくくなる。しかし、やってしまったときには足全体が無くなる。

KORYUOH
記事: 44
登録日時: 7年前

Re: 文字列の操作がうまくいかない(C++)

#3

投稿記事 by KORYUOH » 6年前

間違えた、アドレス先の内容が消失していると思うので関数の宣言を変えるかstd::stringを使いましょう
C言語を使うと自分の足を誤って撃ち抜いてしまうことがある。 C++を使えばそのような間違いを犯しにくくなる。しかし、やってしまったときには足全体が無くなる。

Jimmy
記事: 9
登録日時: 7年前

Re: 文字列の操作がうまくいかない(C++)

#4

投稿記事 by Jimmy » 6年前

KORYUOHさんありがとうございます。

もしかして、ローカルスコープ変数wordの値は関数終了時に破棄されるということですか!?
うまくいかない理由が見えて来ました(このプログラム以外にも何度も起きているので・・・)。

もしそうなら、戻り値型をchar * のまま、getBack3()を使うには、wordはグローバル変数にする方法しかないということですよね?
引数を増やすのは嫌なので・・・

C++で書いている理由は、Cより変数の宣言が自由な場所でできるからです。
本当はC言語をもう少し深めようと思っています。
ですので、stringを使うのまた違う機会にしたいと思います。

Blue

Re: 文字列の操作がうまくいかない(C++)

#5

投稿記事 by Blue » 6年前

呼び出し元で編集するということがないのであれば、この仕様なら引数のポインタを進めたポインタを返すのも
ありかなぁと。

以下、こんなイメージ。

コード:

const char* getBack3(const char* str)
{
	const char* p = str;
	int len = strlen(str);
	if (len >= 3) {
		p += len - 3;
	}
	return p;
}

Jimmy
記事: 9
登録日時: 7年前

Re: 文字列の操作がうまくいかない(C++)

#6

投稿記事 by Jimmy » 6年前

少し時間が開いてしまいました。
>間違えた、アドレス先の内容が消失していると思うので関数の宣言を変えるかstd::stringを使いましょう。
原因がわかってスッキリしました!ありがとうございます。

Blueさん
「うしろ3文字」なら、確かにBlueさんの方法もありですね。
気が付きませんでした。本当に文字列を取得したいとき、特定の条件の文字列の位置を返すときとで使い分けたいと思います。
ありがとうございます。

閉鎖

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