質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

413閲覧

ポインタを使って動的配列の管理、表示がしたいです

do_Shiro_to

総合スコア15

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/07/28 01:04

編集2019/07/28 04:40

前提・実現したいこと

ど素人の初歩的な質問ですみません。いくら調べても、よくわからなかったので質問させていただきます。
ユーザーの数、名前、年齢を聞いて、名前の文字数を表示するプログラムを作りたいのですが、思ったように表示されません。
正直言って、まだポインタを完璧に理解できていないので、どう直せばいいのかわかりません…

理想の結果は:
The name Tanaka has length 6
The name Satou has length 5

発生している問題・エラーメッセージ

とくにエラーメッセージなどは、表示されませんが、データの保存がうまくいきません。 一人目の名前はちゃんと記録されるのですが、二人目以降が全部最初の人の名前になってしまいます。

該当のソースコード

C++

1#include <iostream> 2#include <string> 3using namespace std; 4 5// Person class 6class Person 7{ 8private: 9 string name; 10 int age; 11public: 12 Person() { 13 name = ""; 14 age = 0; 15 } 16 17 Person(string name1, int age1) 18 { 19 name = name1; 20 age = age1; 21 } 22 23 string setName(string name1) { 24 name = name1; 25 return name; 26 } 27 28 int setAge(int age1) { 29 age = age1; 30 return age; 31 } 32 33 int getAge() { return age; } 34 string getName() { return name; } 35}; 36 37 38// Prototypes 39int lengthOfName(Person* p); 40 41int main() 42{ 43 const int LENGTH = 30; 44 int i, ages; 45 char* names = nullptr; 46 names = new char[LENGTH]; 47 48 Person* pPerson = nullptr; 49 50 cout << "Please enter number of persons: "; 51 cin >> i; 52 53 pPerson = new Person[i]; 54 55 56 for (int index = 0; index < i; index++) { 57 58 cout << "Please enter your name: "; 59 cin.get(); 60 cin.getline(names, LENGTH); 61 62 63 cout << "Please enter your age: "; 64 cin >> ages; 65 66 pPerson[index].setName(names); 67 pPerson[index].setAge(ages); 68 69 70 } 71 72 for (int index = 0; index < i; index++) { 73 cout << "The name " << pPerson->getName() 74 << " has length " << lengthOfName(pPerson) << endl; 75 76 77 } 78 79 delete[]pPerson; 80 81 return 0; 82} 83 84//ここはいじらなくて大丈夫です 85int lengthOfName(Person* p) 86{ 87 string name = p->getName(); 88 return name.length(); 89} 90 91/*実行結果 92The name ??? has length 3 93The name ??? has length 3 94The name ??? has length 3 95*/ 96

試したこと

いろんなサイトを調べて、なんとかここまでこぎつけましたが、これ以上はどう直せばいいのかよくわかりません。

追記

いわれた通り、インデックスを加えたらちゃんと名前が表示されるようになりましたが、もう一つの目的である文字数の表示がうまくいきません。

C++

1for (int index = 0; index < i; index++) { 2 cout << "The name " << pPerson[index].getName() 3 << " has length " << lengthOfName(pPerson) << endl;

現在の実行結果は
The name Tanaka has length 6
The name Satou has length 6
The name Ito has length 6
といった感じです。

これをどうにかして上記の理想の実行結果にしたいです。

C++

1lengthOfName(pPerson)

おそらくこの部分がうまく参照できず、一番最初の名前を引っ張ってきているみたいです。
どうすれば解決するのでしょうか??

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

値を設定する方のループでは

C++

1 for (int index = 0; index < i; index++) { 2 //略 3 pPerson[index].setName(names); 4 pPerson[index].setAge(ages); 5 }

なのに、表示では

C++

1 for (int index = 0; index < i; index++) { 2 cout << "The name " << pPerson->getName() 3 << " has length " << lengthOfName(pPerson) << endl; 4 }

表示のループ内の処理にindexが含まれていないのですから、ループの意味がないんじゃないか、ぐらいは気がついて欲しいと思います。


以下質問追記分について

C+

1lengthOfName(pPerson)

おそらくこの部分がうまく参照できず、一番最初の名前を引っ張ってきているみたいです。

ズバリその通り。名前の表示の方も根っこは同じ話なんですけど、なんでそっちは出来てこっちは出来なかったのかしら。

C/C++では、配列はその先頭要素へのポインタで代表されます。配列が単独で記述されれば先頭要素へのポインタと解釈されますし、pがポインタ、iが整数としたとき *(p+i)p[i]は等価、同じ意味を持つという決まりになっています。
この決まりに沿って読み解けば、lengthOfName()関数に与えられたpPersonは、配列としては最初の要素(つまり一人目)へのポインタです。毎回一人目のデータへのポインタを与えているのですから、lengthOfName()関数は毎回一人目の名前の文字数を返してきます。

やりたい仕事から言えば、lengthOfName()関数には配列の欲しいインデックスの要素へのポインタを与えなければいけません。なので、そのようにするなら

lengthOfName( &pPerson[index] )

または

lengthOfName( pPerson+index )

でしょう。
(直したら動いた、だけじゃなくて意味をよく噛み締めてくださいね。この辺、よくわからないまま*を付けたり&を付けたりして動いたらヨシとする、という初心者をよく見かけます。)

投稿2019/07/28 01:21

編集2019/07/28 05:01
thkana

総合スコア7639

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

do_Shiro_to

2019/07/28 02:54

あぁ…そういわれればそうですね!! 難しいことばかり気にしていて、簡単なことを完全に見落としていました!! 灯台下暗しですね…
do_Shiro_to

2019/07/28 03:08

表示部分も直してみたら、ちゃんと名前表示はできるようになったのですが、名前の文字数がまだ正しく表示されないみたいです… ほかに直すべき部分がありましたら教えてくださると、助かります。
thkana

2019/07/28 03:54

質問では「どうしたいのか」「なにをやったのか」「どういう結果が得られたのか」がきちんと書いてあって素晴らしかったのですが... 出来たかどうかだけが問題なら「出来てません」でいいですけど、トラブルを解決しようという場面では「直してみたら、正しく表示されない」ではなく、「このように変更したら、こういう結果が得られた」という詳細を書いて下さい。 質問は編集出来ますから、その辺のことを追記すればよいでしょう。 想像だけでいうなら、名前の表示の方だけ直して文字数の方は直していないとかいうことじゃないかと疑いますけれど。
do_Shiro_to

2019/07/28 04:41

かさねがさねすいません… 以後気を付けます。 追記を書いたので、よろしければご確認ください。
do_Shiro_to

2019/07/28 05:23

いわれた通り、やったらできました! そうですね… わからないまま、コピペをくっつけて作っただけじゃじぶんのためにはなりませんね。 反省してしっかりポインタを勉強しなおします…
thkana

2019/07/28 10:07

> コピペをくっつけて作っただけじゃ あれ? それ、思ってたけど書かなかったよなぁ。自分で意識してたんですね。 この短いプログラムで構造体アクセスがあっちは.でこっちは->で。きっとあちこちから寄せ集めてきたんだろうなぁ、と思っていはいたのですが。 「メモリ」のイメージを持って、スジを通して考えれば、ポインタは多少ややこしくはあっても本質的に難しいものじゃないと思います。頑張ってください。
guest

0

C++

1 for (int index = 0; index < i; index++) { 2 cout << "The name " << pPerson->getName() 3 << " has length " << lengthOfName(pPerson) << endl; 4 5 6 }

一人目をi回表示していますよ

lengthOfName(pPerson)

おそらくこの部分がうまく参照できず、一番最初の名前を引っ張ってきているみたいです。
どうすれば解決するのでしょうか??

pPersonpPerson[index]の違いをきちんと理解されていないのでは?

C++

1lengthOfName(pPerson + index)

C++

1lengthOfName(&pPerson[index])

などのようにindex分後ろにずらしてアクセスしないといけません。

投稿2019/07/28 01:17

編集2019/07/28 05:01
SHOMI

総合スコア4079

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

do_Shiro_to

2019/07/28 03:09

なおしたらちゃんと名前表示できました! けど、今度は名前の長さを正しくできてなかったみたいです… ほかに直せる部分があったら、ぜひ教えてほしいです!
SHOMI

2019/07/28 04:14

どのように変更し、どうなったのかを質問文に追記して下さい
do_Shiro_to

2019/07/28 04:42

すみません。 いわれた通り、できるだけわかりやすく追記に書きました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問