2

だから私はC++に慣れようとしています。そして、これがポインタの使用法を実行することになっているタスクです。方法は次のとおりです。

ユーザーに自分の名前と名前を2つの別々の値として入力するように求める関数を記述します。この関数は、追加のポインターを介して両方の値を呼び出し元に返す必要があります。呼び出し元が名前のNULLポインターを渡した場合にのみ、名前の入力を求めるプロンプトが表示されます。

私はいくつかのバージョンを試しました。私が今立ち往生しているのは:

#include <iostream>
#include <string>

using namespace std;


void getFullName(string *p_first, string *p_last) {
    cout << "First name:";
    getline(cin, *p_first);
    if (!p_last) {
        cout << "Last name:";
        getline(cin, *p_last);
    }
}


int main() {

    string first;
    string *p_first = &first;
    string *p_last = NULL;

    getFullName(p_first, p_last);

    cout << *p_first << endl << *p_last << endl;
    return 0;
}

まあ、それはクラッシュします。そして、私は「最後」への参照を渡して、それを指すようにしました。しかし、関数を終了した後、ポインタは再びNULLになります。

4

5 に答える 5

7

演習のテキストに誤りがあると思います。次のように読みます。

ユーザーに自分の名前と名前を2つの別々の値として入力するように求める関数を記述します。この関数は、追加のポインターを介して両方の値を呼び出し元に返す必要があります。呼び出し元が名前にNULL以外のポインターを渡した場合にのみ、名前の入力を求めるプロンプトが表示されます。

現状では、コードはnullポインターを逆参照することにより、未定義の動作を引き起こします

void getFullName(string *p_first, string *p_last) {
    cout << "First name:";
    getline(cin, *p_first);
    if (!p_last) {    /* <-- This test should be inverted */
        cout << "Last name:";
        /* Now, you get here only when p_last == NULL. On the next line, 
         * you dereference that null-pointer and try to read a string into 
         * non-existing memory: recipe for disaster.
         * With the condition inverted, you would only get here if you have 
         * a string to store the text in. */ 
        getline(cin, *p_last);
    }
}
于 2013-01-20T15:25:16.270 に答える
0

ポインタを使用しないでください。このためのポインタは必要ありません。参照によってパラメータを渡すだけです。

void getFullName(string& p_first, string& p_last) 

ただし、問題は、->未定義の動作p_lastである間接参照を行っていることです。NULL

if (!p_last) {  //this evaluates to true, because p_last==NULL
    cout << "Last name:";
    getline(cin, *p_last);
}
于 2013-01-20T14:43:09.367 に答える
0

あなたの質問があなたが追加を使用すると述べていることを考えると、私はそれを次のように書きます:

string getFullName()
{
    string first, last;
    cout << "First name:";
    getline(cin, first);
    cout << "Last name:";
    getline(cin, last);
    return first + last;  // note use of additional
}
于 2013-01-20T14:50:47.400 に答える
0

それが機能しない理由は、toの呼び出しが2番目の引数としてgetline文字列参照(basic_string<>&)を取り、nullポインターを逆参照して通過させるためです。これはほとんどの場合エラーになります。new通過するには新しい文字列が必要になりますが、これを返す方法がないため、メモリリークが発生することがほぼ確実であるため、これはお勧めできません。

ポインタが変更されることを期待してポインタを渡す場合、したがって、有効なポインタを提供する必要がある戻り値として機能します。

于 2013-01-20T14:55:45.547 に答える
0

まず第一に、割り当てに誤りがあるか(それが完全な割り当てである場合)、または割り当ての解釈に誤りがあります。p_lastが保存されるべき文字列を指している場合、名前を読み取るバージョンは次のとおりです。

void getFullName(string *p_first, string *p_last) {
    cout << "First name:";
    getline(cin, *p_first);
    if (p_last) {
        cout << "Last name:";
        getline(cin, *p_last);
    }
}

これは、NULLでない場合はラストネームとして使用p_lastし、そうでない場合はユーザーからラストネームを読み取り、どちらの場合もフルネームをp_first次のように返すバージョンです。

void getFullName(string *p_first, string *p_last) {
    cout << "First name:";
    getline(cin, *p_first);
    string lastname;
    if (!p_last) {
        cout << "Last name:";
        getline(cin, lastname);
    } else {
        lastname = *p_last;
    }
    *p_first += lastname;
}

これは、ポインタへの参照を使用してp_lastNULLかどうかを変更するバージョンです。

void getFullName(string *p_first, string *&p_last) {
    cout << "First name:";
    getline(cin, *p_first);
    if (!p_last) {
        p_last = new string;
        cout << "Last name:";
        getline(cin, *p_last);
    }
}

ただし、これらはどれもあなたの割り当てと一致しません。

于 2013-01-20T16:21:41.807 に答える