2

私は動的記憶を学んでいますが、何かがうまくいっていません。数値を入力として受け取り、そのサイズの配列を作成することになっている関数があります。

class Doctor {
public:
    Doctor();
    void fillOut();
    void listPatients();
    void patientReset();
    ~Doctor();
private:
    string name;
    int numPatients;
    string *patientList;
};

Doctor::Doctor() {
    name = "";
    numPatients = 0;
    patientList = new string[numPatients];
}

(3番目のコードブロックで最も関連性の高いコード)。

void Doctor::fillOut() 
{
    string buffer = "";
    string buffer2 = "";
    size_t found;
    bool valid = false;
    int numP = 0;
    int tester = 0;
    bool validNum = false;

    while(!valid) 
    {
        cout << "Enter doctor name: ";
        getline(cin, buffer);
        found = buffer.find_first_of("1234567890!@#$%^&*()-=_+/<>?;':][");
        if(string::npos == found) 
        {
            name = buffer;
            valid = true;
        }
    }

    while (!validNum) 
    {
        cout << "\nEnter number of patients: ";
        buffer = "";
        getline(cin, buffer);
        buffer2 = buffer;
        stringstream ss(buffer);
        if(ss >> tester) 
        {
            stringstream ss2(buffer2);
            ss2 >> numP;
            validNum = true;
        }
        else 
        {
            cout << "Not a number. Please try again." << endl;
        }
    }

    patientList = new string[numP];
    cout << patientList->size() << endl;
    for(int i = 0; i < (numP + 0); i++) 
    {
        valid = false;
        while(!valid) 
        {
            cout << "\nEnter patient " << (i + 1) << ": ";
            getline(cin,buffer);
            found = buffer.find_first_of("1234567890!@#$%^&*()-=_+,./<>?;':][");
            if(string::npos == found) 
            {
                *(patientList + i - 0) = buffer;
                //patientList[i-1] = buffer;
                valid = true;
            }
            else 
            {
                valid = false;
            }
        }
    }
}

次に、リストの内容を表示してみます。

void Doctor::listPatients() 
{
    cout << "size: " << patientList->size() << endl;
    cout << "\nDoctor: " << name << endl;
    for(int i = 0; i < (patientList->size() - 1); i++) 
    {
        cout << "Patient " << (i+1) << ": " << patientList[i] << endl;
    }
    cout << "end patients" << endl;
}

しかし、何らかの理由で、サイズが配列のサイズではないため、送信する数値。たとえばfillOut()、関数にサイズを出力させます。毎回サイズを0として出力します。次に、でlistPatients()、サイズを再度印刷するものがあり、正しく実行されていることを確認します。最初に3を入力した場合、この関数では出力5があります。

私は完全に神秘的です。

4

3 に答える 3

6

この行は、配列の最初の文字列の長さである にpatientList->size()相当します。配列を割り当てた時点では、結果は常にゼロです。それ以外の場合は、最初の文字列の長さです。patientList[0].size()patientList

C++ でコンテナーを作成する好ましい方法は、std::vectorまたはstd::arrayです。あなたの場合は、コードが動的にstd::vector割り当てるため、使用がより適切です。patientList

于 2012-07-14T00:36:42.430 に答える
2

わかりましたので、patientList を string* として宣言しますが、これに対して size() を呼び出すと、実際には、作成した配列の最初の項目に対して呼び出しています。コードがコンパイルされた唯一の理由は、 string に size() 関数があり、これが配列に含まれる型であるため、実際には patientList が配列の先頭の項目 (文字列) を指しているためです。一般に、配列には size() 関数がありません。

ただし、もう1つの問題はループにあります

for(int i = 0; i < (patientList->size() - 1); i++) {
                 ^
                 ^  
    cout << "Patient " << (i+1) << ": " << patientList[i] << endl;
}

これにより、患者リストが終了する前にループが終了します。使用する必要があります

for(int i = 0; i < patientList->size(); i++) {                                      
    cout << "Patient " << (i+1) << ": " << patientList[i] << endl;
}

ここで std::vector を使用して文字列を配置することをお勧めします。ここでも注意してください

   if(string::npos == found) {
        *(patientList + i - 0) = buffer;
        //patientList[i-1] = buffer;
        valid = true;
    }
    else {
        valid = false;
    }

if ステートメントが true の場合にのみ配列に代入するため、false の場合の配列内のインデックスは初期化されていないままになります。正直なところ、最初からやり直して、文字列のベクトルを使用します。

于 2012-07-14T00:38:10.857 に答える
2

Ok, I found your problem. You are declaring an array of strings. But a raw array is really just a pointer to the contents of the array. When you call ->size, it dereferences that pointer, which points to the first string in the array and tells you the size of that string.

If you want an array that actually knows its size, use std::array.

于 2012-07-14T00:24:06.153 に答える