2012-04-09 5 views
1

als C++ Anfänger ich den folgenden Code geschrieben haben:cin und char-Array Zeiger in struct

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; 
} 

Mein Problem ist, dass ich nicht meinen Kopf um ein Problem bekommen, wo ich eine segfault bekommen beim Laufen Das Programm an der Stelle muss ich in das Modell des Autos eingeben. Kann mir bitte jemand erklären, was ich falsch mache?

Soweit ich es verstehe, gebe ich einen Zeiger auf das Array "make", die es funktionieren sollte. Ist mein Verständnis weit weg?

Vielen Dank im Voraus Dan

Antwort

4

Vier Fragen, die ich sofort sehen:

Ausgabe 1

In Ihrem struct, Sie haben:

char * make[200];

In Englisch, das sagt: „ein Array erstellen von 200 Zeigern auf Zeichen ", wenn ich denke, dass Sie sagen möchten," erstellen Sie ein Array von 200 Zeichen. " Sie sollten also stattdessen haben:

char make[200].

Ausgabe 2

Du Looping um 1 starten. Dadurch wird das erste Auto im Array übersprungen - denken Sie daran, Arrays sind nullindiziert. So sollten Sie stattdessen:

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

und für die Anzeige, könnte man sagen:

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

Ausgabe 3

Wo Sie sagen:

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

und

cin >> Cars->manfYear;

Wo in diesen Zeilen geben Sie an, welches Auto der Benutzer bevölkern wird? Nirgends. Wenn Sie mit i loopen, müssen Sie tatsächlich i erwähnen.Diese sollten arbeiten:

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

und

cin >> Cars[i].manfYear;

Beachten Sie, dass wir . verwenden, nicht ->. Dies liegt daran, dass die Elemente im Array Cars tatsächliche Instanzen sind, keine Zeiger. Das Cars Array ist selbst ein Zeiger, aber nicht sein Inhalt.

Ausgabe 4

Alle Kredite zu @Ben C, die diesem ersten wiesen darauf hin: den >> Operator mit getline() Funktion auf cin Mischen zu seltsamen Verhalten führen kann, mit übrig gebliebenen CR ‚s aus >> in den Anruf getline() gehen. Sie könnten entweder alle >> (Nachteil: Sie haben nicht die 200 Grenze beim Lesen der Marke durchgesetzt) ​​oder alle cin.getline() (Nachteil: Sie müssen Zeichenfolge Puffer verwenden und dann konvertieren sie für die Anzahl der Autos und Jahr), oder setzen cin.ignore() nach jedem Aufruf von >>, etwa so:

cin >> num; 
cin.ignore(); 

und

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

Auch hier werden alle Kredite an @Ben C diese erste für zu bemerken.

Last but not least

Vereinbarungsklassen/structs haben Kapitalnamen und Variablen Klein/Camelcase-Namen. Erwägen Sie, die struct von car zu Car umzubenennen, und das Array von Cars zu cars. Mit anderen Worten, die Umkehrung der Kapitalisierung haben Sie gerade jetzt.

Schließlich stimme ich mit allen anderen Plakaten hier überein: Sie sollten string anstelle von char Arrays verwenden.

2

Verwenden Sie zuerst string statt armen alten C char[].

Als nächstes: Sie wollen nicht char * make[200];. Sie wollen char make[200];. char * make[200] ist ein Array von 200 Zeigern zu char s, die als 200 nullterminierte Strings verwendet werden können - aber dann müssten Sie new[] jeder von ihnen. Verwenden Sie einfach char make[200]; und cin.getline(Cars->make, 200);.

+0

Brilliant. Alles ergibt jetzt Sinn. Sehr geschätzt. – Dan

+0

mit Ich bin verwirrt Nun, was passiert, ich habe jetzt den folgenden Code: int main (void) { \t struct Auto { \t \t char make [200]; \t \t int manfJahr; \t}; \t int num = 0; \t cout << "Wie viele Autos möchten Sie katalogisieren?"; \t cin >> num; \t Auto * Autos = neues Auto [num]; \t \t for (int i = 0; i > Autos [i] .manfJahr; \t \t // Autos ++; \t} Jetzt habe ich nicht einmal die Möglichkeit, das manfyear eingeben, läuft das Programm nur, aber druckt zufällige Daten. – Dan

1

Zunächst ist char *make[200] keine Zeichenfolge mit maximal 200 Zeichen, sondern 200 Zeiger auf char.

zweite Sache: Sie dereferencing den Zeiger in cin.getline mit *: Was passiert, ist, dass Sie den Wert in der ersten Zelle der 200 char* Zeiger enthalten erhalten. Aber Sie haben die einzelnen Zeiger nicht initialisiert, nur die höhere, also erhalten Sie einen segfault.

Ändern Sie einfach char* make[200] zu char make[200] und *Cars->make zu Cars[i].make.

+0

s/'->' /'./. 'Autos' ist ein' Auto * ', kein' Auto ** '. –

1

Zu allererst Arrays in C++ von 0..n-1 indiziert sind, so dass Ihre Schleife von

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

Zweitens haben Sie make als 200-Element-Array von erklärt Zeiger bis char; Dies ist am wahrscheinlichsten nicht was Sie wollen. Wenn make soll eine Zeichenfolge speichern, deklarieren es als eine einfache Anordnung von char:

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

Schließlich umschreiben Ihre getline Ruf als

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

Obwohl Cars als Zeiger deklariert wird, Sie kann den Subscript-Operator darauf verwenden als ob es ein Array wäre; indem Sie dies tun, implizit dereferenzieren Cars, da a[i] als *(a + i) interpretiert wird. Dies bedeutet auch, dass Sie den Komponentenauswahloperator . anstelle des Operators -> verwenden, da der Typ Cars[i]car, nicht car * ist.

2

char * make[200] deklariert ein Array von 200 Zeigern; Ich schätze, das ist nicht das, wonach Sie suchen.

Wenn Sie nur eine Zeichenfolge speichern möchten, empfehle ich stattdessen einen Blick auf den C++ string Typ.

#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; 
    } 
} 

Es gab auch ein paar andere kleine Fehler mit Ihrem Code.

1) Sie haben Cars->manfYear verwendet - dies wird Sie immer nur auf das erste Element Ihres Arrays verweisen. Ich nehme an, du willst das nicht; Mit der Subskriptsyntax nach Cars[i-1].manfYear greifen Sie auf ein einzelnes Autoobjekt in Ihrem Array zu. (Denken Sie daran, dass Array-Indizes bei Null anfangen - es wäre eigentlich mehr idiomatischen Sinn für Ihre für Schleifenvariable macht bei Null zu beginnen und wirklich)

2) Seien Sie vorsichtig bei der Art und Weise std::getline und das >> Symbol arbeitet zusammen . der >> (stream extraction operator) hinterlässt oft irgendwelche Zeilenumbruchzeichen, was bedeutet, dass Sie vielleicht ein "seltsames" Verhalten bei Ihren Calls zu getline sehen. Wenn Sie die beiden zusammen mischen, hilft Ihnen die Verwendung von etwas wie std::cin.ignore(), das Zeilenumbruchzeichen zu verwerfen.