2009-04-01 11 views
0

So habe ich eine Klasse Objekttyp, myClass classType als global. was nicht happeing also würdelesen Textdatei in Klasse Objekttyp Array (C++)

// MyClass.h 
{ 
    private: 
    char FirstName; 
    char LastName; 
    char MiddleName; 
    int ID; 
    int Age; 
}; 

// Globals 
const int myIndex = 256; 
myClass classType[ myIndex ]; 

int main() 
{ 

    // assume preprocessors are included 

    cout << "Enter File: "; 
    cin >> cArray; 
    if (!inFile.good()) 
    { 
    cout << "Wrong?" << endl; 
    } 
    inFile.open(cArray); 
    while (!inFile.eof()) 
    { 
    linecount++ // giving me 1 and not counting the file lines 

inFile.read((char *) &myType[linecount], sizeof(myClass)); 

    } 
} 

Das ist eine grobe Vorstellung davon, welche Haupt sieht aus wie heute für mich bevorzugen. Ich habe myClass.cpp überhaupt noch zu benutzen! Meine Textdatei ist dieses Format:

Vorname Name ID-Nummer Alter ...

Nach Debuggen, ich feststellen, dass das Newline-Zeichen nicht erkannt wurde und jetzt ist alles gebündelt in, auf dem gleicher Index! Wie mein Inkrement funktioniert nicht oder etwas ..

Ich wollte für viele Zeilen erhöhen sie sind in der Datei. (mehr als eins) Ich versuche, den Linecount (idx) in der Hoffnung zu beheben, dieses Problem vollständig zu beheben.

Meine privaten Mitglieder, FirstName LastName und so weiter, wie ich oben schrieb, sind vorhanden, wenn Sie den myclasstyp debuggen und ziehen. Ich brauche nur, um sie mit ihren richtigen varaible zu bekommen. Ich hoffe nur, dass die Funktion ifstream :: read() mich nicht in eine schlechte Richtung führt.

Irgendwelche Vorschläge?

+0

Ihre Namen werden jeweils nur aus einem Zeichen erklärt. das scheint falsch zu sein. – unwind

+0

Es gibt eine Reihe von Problemen mit Ihrem Code, die eine Kompilierung verhindern. Sie benötigen "struct myClass" vor der Definition dieser Klasse; Sie müssen cArray, linecount und inFile irgendwo angeben; FirstName, LastName und MiddleName sind derzeit jeweils ein einzelnes Zeichen. –

+0

Ihr Problem sieht viel wie eine Hausaufgabe aus. Sie sollten es selbst herausfinden, basierend auf dem Kursmaterial, das Sie haben. Dies wird sicherstellen, dass Sie tatsächlich etwas lernen, anstatt nur die Aufgabe mit einer Lösung von hier zu übergeben. – lothar

Antwort

0
  • Ich habe die Verwendung von Boost :: Serialisierung für die gleichen Ziele empfohlen.
  • Warum erhöhen Sie den Zeilenzähler vor dem Lesen einer Zeile? Sie lassen das erste Element von myType nicht initialisiert.
  • Wenn Sie ein Textdateiformat verwenden, warum verwenden Sie die Lesefunktion?
0

Mehrere Punkte;

  • was ist cArray?
  • Sie müssen überprüfen, ob die Datei()
  • die EOF() Funktion wird mit istAuf geöffnet nur das Ende der Datei erkennen, nachdem Sie etwas gelesen haben
  • sollten Sie std :: getline() werden unter Verwendung von Zeilen zu lesen
  • wie es in einem Kommentar darauf hingewiesen, sind die Namen in der Klasse einzelne Zeichen, sollten sie mit read (buf, Größe) funktioniert nicht, wenn Sie Ihre Daten von std :: strings
0

Sie nähern werden kommt eine Textdatei. Er füllt buf mit den Bytes, die vom Eingang gelesen werden. Sie können ein Objekt im Speicher nicht auf diese Weise "füllen". lesen (buf, Größe) funktioniert nur mit Binärdaten.

Ich würde den Stream-Operator >> überladen, um die tatsächlichen Parsing der Textdaten zu tun. Die Ausgabe wird in dem als Referenz übergebene Objekt gespeichert werden:

istream& operator>> (istream& in, MyClass& val);

1
// MyClass.h 
{ 
    private: 
    char FirstName; 
    char LastName; 
    char MiddleName; 
    int ID; 
    int Age; 
}; 

Was diese Struktur/Klasse ist?Ich schätze, dass es myClass ist. Anyway myClass ist kein sinnvoller Name.

  1. Vorname/Nachname/Zweiter Vorname Eighter sind Initialen - was bedeutet, dass der Name falsch ist - oder sind schlecht typisiert. Was Sie suchen, ist Eighter Std :: String oder Char *.
  2. Traditionell ID ist das erste Feld - wenn es benötigt wird.

``

// Globals 
const int myIndex = 256; 
myClass classType[ myIndex ]; 

Als Faustregel gilt: - nie Globals verwenden. Sie wird Probleme haben.

int main() 
{ 

    // assume preprocessors are included 

    cout << "Enter File: "; 
    cin >> cArray; 

Was ist cArray?

if (!inFile.good()) 

Wo ist InFile definiert? Warum überprüfen Sie den E/A-Status vor jeder E/A-Operation in diesem Stream?

{ 
    cout << "Wrong?" << endl; 
    } 
    inFile.open(cArray); 

Gut. Ist es nicht einfacher zu schreiben ifstream inFile(cArray)?

während (! InFile.eof()) { linecount ++ // me 1 geben und nicht das Zählen der Dateizeilen

Sie suchten nach Überlauf fragen. Was ist, wenn die Datei mehr 256 Zeilen hat? Welches schlechteste Programm wird nicht abstürzen - es wird wahrscheinlich an einem unbestimmten Ort schreiben.

inFile.read((char *) &myType[linecount], sizeof(myClass)); 
  1. Verwenden Sie niemals Binärformaten es sei denn, Sie zu haben. Sie sind sehr schwer zu debuggen. Wenn Sie ein schönes, einfaches Textformat haben, müssen Sie nur einen Texteditor testen, um Test-Eingabedateien zu bearbeiten. Mit binary haben Sie keine Garantie, dass der Fehler im Programm nicht im Testfall ist.
  2. Evern wenn Sie tun verwenden Binärformat tun nicht lesen Sie es so. In der Tat haben Sie keine Möglichkeit festzustellen, ob der Compiler die Offsets nicht geändert hat. Zum Beispiel wird ID normalerweise einen Offset von 4 Bytes haben. Der Compiler kann ihn jedoch optimieren.

    Zusätzlich haben Sie keine Möglichkeit, die Größe von ID und Age zu bestimmen, außer sie sind größer als 2 Bytes. Sie sind in der Regel 4, aber auf einigen 64-Bit-Compiler (IMHO ist so richtig, wo int == einzelnes Wort) thay kann 8. In Zukunft Thay kann 16 sein (wenn es 128-Bit-Computer sein wird). Du denkst vielleicht, dass es niemals so ist, aber auf die gleiche Weise "768 K war genug für alle" (das war damals viel).

Wenn Sie versuchen, Text in einer solchen Art und Weise

} 
} 

zu lesen, wenn Sie die Eingabe bestätigen müssen (in diesem Fall iostreams ist nicht das beste Werkzeug):

class person 
{ 
public: 
    person (const std::string &first_name, 
      const std::string &last_name, 
      const std::string &middle_name, 
      int    id, 
      int    age) 
      : m_first_name(first_name), 
      m_last_name(last_name), 
      m_middle_name(middle_name, 
      m_id(id), 
      m_age(age) {} 
private: 
    std::string m_first_name, m_last_name, m_middle_name; 
    int m_id, m_age; 
}; 
// Lots of other code 
std::vector<person> people; 
while(...) 
    { 
    std::string first_name, last_name, middle_name; 
    int id, age; 
    in_file >> first_name >> last_name >> middle_name >> id >> age; 
    person p(first_name, last_name, middle_name, id, age); 
    people.push_back(p); 
    } 

Es kann gekürzt werden und es muss gefüllt werden aber: 1.Verwenden Sie nette C++ - Funktionen wie AWL (Sie müssen sich keinen Index merken oder Sie müssen sich keine Gedanken über einen Vektorüberlauf machen) 2. Es verwendet das Textformat