1

C++ の初心者として、次のコードを作成しました。

int main(void){
struct car{
    char * make[200];
    int manfYear;
};

int num=0;

cout << "How many cars do you wish to catalogue? ";
cin >> num;
car * Cars = new car [num]; 

for (int i=1;i<=num;i++){
    cout << "Car #" << i << ":" << endl << "Please enter the make: ";
    cin.getline(*Cars->make,200);
    cout << "Please enter the year made: ";
    cin >> Cars->manfYear;
}

私の問題は、車のモデルを入力する必要がある時点でプログラムを実行すると、segfault が発生するという問題に頭を悩ませることができないことです。誰かが私が間違っていることを説明してもらえますか?

私が理解している限り、それを機能させる配列「make」へのポインターを渡しています。私の理解は途方もないですか?

前もって感謝します ダン

4

5 に答える 5

4

すぐにわかる 4 つの問題:

問題1

structには、次のものがあります。

char * make[200];

英語では、これは「文字への 200 個のポインターの配列を作成する」と言っています。したがって、代わりに次のものが必要です。

char make[200].

問題 2

からループしてい1ます。これにより、配列の最初の車がスキップされます。配列のインデックスは 0 であることに注意してください。したがって、代わりに次のものが必要です。

for (int i = 0 ; i < num ; i++)

表示目的で、次のように言うことができます。

cout << "Car #" << (i+1) << ":" << endl << "Please enter the make: ";

問題 3

あなたが言うところ:

cin.getline(*Cars->make,200);

cin >> Cars->manfYear;

これらの行のどこで、ユーザーがどの車に乗り込んでいるかを指定していますか? どこにもない。でループしている場合はi、実際に言及する必要がありますi。これらは動作するはずです:

cin.getline(Cars[i].make,200);

cin >> Cars[i].manfYear;

.ではなくを使用していることに注意してください->。これは、Cars配列内の項目がポインタではなく実際のインスタンスであるためです。Cars配列自体はポインターですが、その内容ではありません。

問題4

これを最初に指摘した@Ben Cの功績:>>演算子とgetline()function onを混在させると、残りのが呼び出しに入るというcin奇妙な動作につながる可能性があります。all (欠点: make を読み取るときに制限が適用されない) または all (欠点: 文字列バッファーを使用してから、車の数と年に変換する必要がある) のいずれかを使用するか、各呼び出しの後に置くことができます。の、次のように:CR>>getline()>>200cin.getline()cin.ignore()>>

cin >> num;
cin.ignore();

cin >> Cars[i].manfYear;
cin.ignore();

繰り返しますが、これに最初に気付いた@Ben Cの功績です。

最後だが大事なことは

慣例により、クラス/構造体には大文字の名前が付けられ、変数には小文字/キャメルケースの名前が付けられます。from の名前を に変更し、配列の名前をstructfromcarに変更することを検討してください。つまり、現在の大文字と小文字の逆です。CarCarscars

最後に、ここで他のすべてのポスターに同意します。配列stringの代わりに使用することを検討する必要があります。char

于 2012-04-09T21:49:41.340 に答える
2

まず、stringかわいそうな古い C の代わりに使用しますchar[]

次へ: したくないchar * make[200];. あなたがしたいchar make[200];char * make[200]は s への 200 個のポインターの配列であり、char200 個の null で終わる文字列として使用できますが、new[]それぞれを使用する必要があります。char make[200];とを使用するだけcin.getline(Cars->make, 200);です。

于 2012-04-09T21:34:42.060 に答える
2

char * make[200]200 個のポインターの配列を宣言します。これはあなたが求めているものではないと思います。

string単純に文字列を格納する場合は、代わりに C++ 型を検討することをお勧めします。

#include <iostream>
#include <string> 

int main()
{
    using namespace std;

    struct car
    {
        string make;
        int manfYear;
    };

    int num=0;

    cout << "How many cars do you wish to catalogue? ";
    cin >> num;
    car * Cars = new car [num]; 

    for (int i=1;i<=num;i++)
    {
        cout << "Car #" << i << ":" << endl << "Please enter the make: ";
        std::cin.ignore();
        getline(cin, Cars[i-1].make);
        cout << "Please enter the year made: ";
        cin >> Cars[i-1].manfYear;
    }
}

コードには他にもいくつかの小さな問題がありました。

1)使用していましたCars->manfYear-これは、配列の最初の要素を指すだけです。あなたはそれを望んでいないと思います。のように添え字構文を使用するCars[i-1].manfYearと、配列内の個々の車のオブジェクトにアクセスできます。(配列インデックスはゼロから始まることを覚えておいてください! - 実際には、forループ変数がゼロから始まる方がより慣用的な意味があります)

std::getline2) 方法と>>記号が連動することに注意してください。(ストリーム抽出演算子) は多くの場合、>>改行文字を残します。これは、getline の呼び出しで「奇妙な」動作が発生する可能性があることを意味します。2 つを混ぜている場合は、次のようなものを使用するstd::cin.ignore()と、改行文字を破棄するのに役立ちます。

于 2012-04-09T21:43:36.830 に答える
1

まず、char *make[200]最大 200 文字の文字列ではなく、 への 200 個のポインタcharです。

2 つ目: でポインターを逆参照していますcin.getline: *200 個のポインターの最初のセルに含まれる値を取得しchar*ます。ただし、単一のポインターを初期化せず、より高いレベルのポインターのみを初期化したため、segfault が発生します。

とに変更char* make[200]するだけです。char make[200]*Cars->makeCars[i].make

于 2012-04-09T21:35:56.650 に答える
1

まず、C++ の配列は 0..n-1 からインデックス付けされるため、ループを実行する必要があります。

for (int i = 0; i < num; i++) { ... }

次に、へのポインターmakeの 200 要素の配列として宣言しました。これはおそらくあなたが望むものではありません。文字列を格納することになっている場合は、次のプレーン配列として宣言します。charmakechar

struct car{
      char make[200];
      int manfYear;      
}; 

getline最後に、呼び出しを次のように書き直します。

cin.getline(Cars[i].make, sizeof Cars[i].make); // fixed per comment below

はポインターとして宣言されていCarsますが、添字演算子を配列のように使用できます。Carsそうすることで、a[i]は として解釈されるため、暗黙的に を逆参照し*(a + i)ます。これは、 のタイプがis , notであるため.、演算子ではなくコンポーネント選択演算子を使用することも意味します。 ->Cars[i]carcar *

于 2012-04-09T21:43:27.563 に答える