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

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

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

C++/CLIは、.NET Frameworkの共通言語基盤であるCLI向けにC++を拡張したプログラム言語です。前身のC++マネージ拡張と比較するとシンプルで分かりやすい構文になっており、高い可読性を持ちます。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

C++

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

Q&A

解決済

3回答

1004閲覧

C++勉強中 文字列数を上手く取得できない

ArMigELo

総合スコア76

C++/CLI

C++/CLIは、.NET Frameworkの共通言語基盤であるCLI向けにC++を拡張したプログラム言語です。前身のC++マネージ拡張と比較するとシンプルで分かりやすい構文になっており、高い可読性を持ちます。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

コードレビュー

コードレビューは、ソフトウェア開発の一工程で、 ソースコードの検査を行い、開発工程で見過ごされた誤りを検出する事で、 ソフトウェア品質を高めるためのものです。

C++

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

0グッド

0クリップ

投稿2021/11/02 08:10

#実現したいこと
文字列の数を正しく取得したいです。

##現状
文字列数出力が「11」になってしまい、正しい文字列数「8」を取得できません。
***で区切られている真ん中のコードを記述する課題に取り組んでいます。
[return getConnectedString().length();]の部分が上手くいっていなそうです。
ご教授お願い致します。

###コード

C++

1#include <iostream> 2using namespace std; 3 4class TwoStrings{ 5 private: 6 //1つ目の文字列 7 string m_string1; 8 //2つ目の文字列 9 string m_string2; 10 public: 11 //1つ目の文字列を設定 12 void setString1(string s); 13 //2つ目の文字列を設定 14 void setString2(string s); 15 //1つ目の文字列を取得 16 string getString1(); 17 //2つ目の文字列を取得 18 string getString2(); 19 //2つの文字列をつないだものを取得 20 string getConnectedString(); 21 //getConnectedString()で得られる文字列の長さを取得 22 int getConnectedLength(); 23}; 24 25//******************************************************************************************** 26 27void TwoStrings::setString1(string s){ 28 m_string1 = s; 29} 30 31string TwoStrings::getString1(){ 32 return m_string1; 33} 34 35void TwoStrings::setString2(string s){ 36 m_string2 = s; 37} 38 39string TwoStrings::getString2(){ 40 return m_string2; 41} 42 43string TwoStrings::getConnectedString(){ 44 return m_string1.append(m_string2); 45} 46 47int TwoStrings::getConnectedLength(){ 48 return getConnectedString().length(); 49} 50 51//******************************************************************************************** 52 53int main(){ 54 TwoStrings s; 55 s.setString1("Hello"); 56 s.setString2("C++"); 57 cout << "1つ目の文字列は" << s.getString1() << endl; 58 cout << "2つ目の文字列は" << s.getString2() << endl; 59 cout << "2つの文字列を合成したものは" << s.getConnectedString() << endl; 60 cout << "合成した文字列の長さは" << s.getConnectedLength() << "文字" << endl; 61 return 0; 62}

出力

C++

11つ目の文字列はHello 22つ目の文字列はC++ 32つの文字列を合成したものはHelloC++ 4合成した文字列の長さは11文字

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

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

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

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

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

guest

回答3

0

まず、プログラミングと言うのは『こう書けばいい』というものではありません。
ロジック(論理)を書き下すのです。

デバッグしましょう。そうすれば理由がはっきりとわかります。
デバッグの方法として、コードを読むことをお勧めします。
実際にはデバッガを使うことを推奨しますが、デバッガの場合、VC++内蔵なのかGDBなのかとかで動か鹿方が変わってきますから、ここでは説明しません。
検索してください。

なのでコードを読む方法を教えます。

コードを読むコツは『一行レベルで、その行が何をしているかを考えながら読む』です。

まずmain関数を探します。そしてそのmain関数内の処理を読みます。

C++

1int main(){ 2 // ToStringsというオブジェクトを生成 3 TwoStrings s; 4 // 生成したオブジェクト(s)のsetString1を呼び出して設定 5 s.setString1("Hello"); 6 // sのsetString2を呼び出して設定 7 s.setString2("C++"); 8 // sのgetString1メンバ関数を呼び出して取得し表示 9 cout << "1つ目の文字列は" << s.getString1() << endl; 10 // sのgetString2メンバ関数を呼び出して取得し表示 11 cout << "2つ目の文字列は" << s.getString2() << endl; 12 // sのgetConnectedStringメンバ関数を呼び出して取得し表示 13 cout << "2つの文字列を合成したものは" << s.getConnectedString() << endl; 14 // sのgetConnectedLengthメンバ関数を呼び出して取得し表示 15 cout << "合成した文字列の長さは" << s.getConnectedLength() << "文字" << endl; 16 // 終了 17 return 0; 18}

さほど問題なさそうですね。では、次に呼び出されたコンストラクタやメンバ関数等も同様にやってみましょう。
『ToStringsというオブジェクトを生成』でコンストラクタが呼ばれています。そのコンストラクタに潜ってみましょう。どうやらデフォルトコンストラクタのようですね。なのでスルー。

更に『生成したオブジェクト(s)のsetString1を呼び出して設定』では、setString1が呼ばれていますから、このメンバ関数にも潜ります。

C++

1void TwoStrings::setString1(string s){ 2 // 単にメンバ変数へセットしているだけ 3 m_string1 = s; 4}

問題なさそう。次の『sのsetString2を呼び出して設定』も同様にやる。

…とやっていき、getConnectedStringメンバ関数も同様にやる。

C++

1string TwoStrings::getConnectedString(){ 2 // メンバ変数 m_string1 に m_string2 を追加して返す 3 return m_string1.append(m_string2); 4}

では、m_string1 とはなんでしょうか。データの状態は? そう、"Hello" になっているはずです。
m_string2 は? そう、"C++"。

つまり、m_string1 = "Hello", m_string2 = "C++" の状態です。

この状態で appendすれば "HelloC++" になりますね。
で、m_string1 もこの文字列になっているはずです。

更に『sのgetConnectedLengthメンバ関数を呼び出して取得し表示』では getConnectedLengthメンバ関数が呼び出されています。

そのメンバ関数に潜ってみましょう。

C++

1int TwoStrings::getConnectedLength(){ 2 // getConnectedStringメンバ関数を呼び出して、その戻り値の長さを取得し、返す 3 return getConnectedString().length(); 4}

えーっと、getConnectedStringメンバ関数が呼ばれていますね。
ではまたgetConnectedStringに潜りましょう。

C++

1string TwoStrings::getConnectedString(){ 2 // メンバ変数 m_string1 に m_string2 を追加して返す 3 return m_string1.append(m_string2); 4}

現在の m_string1 の状態と m_string2の状態を思い浮かべてください。

m_string1 = "HelloC++", m_string2 = "C++" のはずです。

ではこれで連結したらどうなるでしょうか。

m_string1 = "HelloC++C++" のような状態になるはずです。
そう、11文字です。そのため、文字数が合わないのです。

デバッガで追うときも大体こんな感じになります。単にnextだのstepだのprintだのを使って潜るだけです。

投稿2021/11/02 08:38

BeatStar

総合スコア4958

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

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

ArMigELo

2021/11/02 09:01

1度アペンドしてm_string1が「HelloC++」になっているのに、 int TwoStrings::getConnectedLength(){ // getConnectedStringメンバ関数を呼び出して、その戻り値の長さを取得し、返す return getConnectedString().length(); } ここでgetConnectedString()をもう1度読み込むので、「C++」が もう1度アペンドされて「HelloC++C++」という認識で合っていますか??
ArMigELo

2021/11/02 09:10

コードの読み方、書き方をご教授頂きありがとうございます。 一度しか読まれないものだと、固定概念がありました。 自分で読み込むように記述しているのに... 関数が飛び飛びするときよく考えていきます。 詳しく説明して頂きありがとうございました。
BeatStar

2021/11/02 09:16

> ...もう1度アペンドされて「HelloC++C++」という認識で合っていますか?? YES! そうです。本当にそうなのかは実際に 再度 m_string1 を出力してみればいいかと。
ArMigELo

2021/11/02 09:30

cout << "合成した文字列の長さは" << s.getConnectedLength() << "文字" << endl; cout << "1つ目の文字列は" << s.getString1() << endl; cout << "2つ目の文字列は" << s.getString2() << endl; return 0; 「getConnectedLength()」の後に「m_string1」を出力したところ、 「HelloC++C++」が出力されました! 今回は return m_string1.append(m_string2) ↓ return m_string1 + m_string2; に変更しました。
guest

0

getConnectedString() が m_string1 を書き換えています。

C++

1int main(){ 2 TwoStrings s; 3 s.setString1("Hello"); 4 s.setString2("C++"); 5 cout << "1つ目の文字列は" << s.getString1() << endl; 6 cout << "2つ目の文字列は" << s.getString2() << endl; 7 cout << "2つの文字列を合成したものは" << s.getConnectedString() << endl; 8 cout << "1つ目の文字列は" << s.getString1() << endl; // 追加してみると 9 cout << "2つ目の文字列は" << s.getString2() << endl; // わかるよ♪ 10 cout << "合成した文字列の長さは" << s.getConnectedLength() << "文字" << endl; 11 return 0; 12}

投稿2021/11/02 08:18

episteme

総合スコア16614

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

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

ArMigELo

2021/11/02 09:06 編集

int main(){ TwoStrings s; s.setString1("Hello"); s.setString2("C++"); cout << "1つ目の文字列は" << s.getString1() << endl; cout << "2つ目の文字列は" << s.getString2() << endl; cout << "2つの文字列を合成したものは" << s.getConnectedString() << endl; cout << "合成した文字列の長さは" << s.getConnectedLength() << "文字" << endl; cout << "1つ目の文字列は" << s.getString1() << endl; // 追加してみると cout << "2つ目の文字列は" << s.getString2() << endl; // わかるよ♪ return 0; } こちらで出力が「HelloC++C++」になったのでわかりました! 1つ目の文字列はHello 2つ目の文字列はC++ 2つの文字列を合成したものはHelloC++ 合成した文字列の長さは11文字 1つ目の文字列はHelloC++C++ 2つ目の文字列はC++ アドバイスありがとうございました!
guest

0

ベストアンサー

m_string1.append(m_string2)は、m_string1破壊的に変更してしまいます。2回実行すれば、m_string1の中身は"HelloC++C++"になっています。

return m_string1 + m_string2;として、m_string1を変更しない形で書くのが妥当と考えます。

投稿2021/11/02 08:16

maisumakun

総合スコア145184

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

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

ArMigELo

2021/11/02 08:29

出来ました! 足し算+ なども return出来るのですね! string3 = m_string1 + m_string2;等別の要素を用意しないとダメかと思ってました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問