2016-05-06 11 views
0

Ich habe eine Aufgabe, Elemente aus TXT-Datei [Direktzugriffsdatei] in .bin-Datei [feste Länge Record-Datei] (Hausaufgabe) zu kopieren. .txt-Datei enthält Zeichenfolgen. Jede Zeile hat ein Wort. Ich kam unten mit Code, aber ich bin mir nicht sicher, ob das ist, was benötigt wird und sogar leicht korrekt. Jede Hilfe wird nützlich sein! (Ich bin neu in C++)C++ Von Text-Datei zu Binär-Datei

#include <iostream> 
#include <fstream> 
#include <string> 
using namespace std; 
const int buffer_size = 30; 

class Word{ 
    char name[buffer_size]; 
public: 
    void setName() // Trying to get every word from a line 
    { 
     string STRING; 
     ifstream infile; 
     infile.open ("text.txt"); 
     while(!infile.eof()) // To get you all the lines. 
     { 
      getline(infile,STRING); // Saves the line in STRING. 
     } 
     infile.close(); 
    } 
}; 


void write_record() 
{ 
    ofstream outFile; 
    outFile.open("binFILE.bin", ios::binary | ios::app); 
    Word obj; 
    obj.setName(); 
    outFile.write((char*)&obj, sizeof(obj)); 
    outFile.close(); 
} 


int main() 
{ 
    write_record(); 
    return 0; 
} 

NEUER ANSATZ:

class Word 
{ 
char name[buffer_size]; 
public: 
    Word(string = ""); 
    void setName (string); 
    string getName() const; 
}; 

    void readWriteToFile(){ 
     // Read .txt file content and write into .bin file 
     string temp; 
     Word object; 
     ofstream outFile("out.dat", ios::binary); 
     fstream fin ("text.txt", ios::in); 
     getline(fin, temp); 
     while(fin) 
     { 
      object.setName(temp); 
      outFile.write(reinterpret_cast< const char* >(&object),sizeof(Word)); 
      getline(fin, temp); 
     } 
     fin.close(); 
     outFile.close(); 
} 

int main() 
{ 
readWriteToFile(); 


return 0; 
} 
Word::Word(string nameValue) 
{ 
setName(nameValue); 
} 
void Word::setName(string nameString) 
{ 
// Max 30 char copy 
const char *nameValue = nameString.data(); 
int len = strlen(nameValue); 
len = (len < 31 ? len : 30); 
strncpy(name, nameValue, len); 
name[len] = '\0'; 
} 
string Word::getName() const 
{ 

Rückkehr Name; }

+2

Vielleicht interessiert es Sie zu lesen ["Warum wird iostream :: eof innerhalb einer Schleife als falsch angesehen?"] (Http://stackoverflow.com/questions/5605125/why-is-iostreameof-inside-a-loop - Bedingung - als falsch angesehen. –

+0

Vorschlag: Wenn Sie 'std :: string' an dieser Stelle anstelle dessen verwenden dürfen:' char name [buffer_size]; 'do it. Rette dir viel Schmerz. Ja. Viel Schmerz. – user4581301

+0

@JoachimPileborg Danke für den Rat. Ich bin immer noch auf der Suche nach der Antwort auf meine Frage! Lassen Sie mich wissen, wenn Sie irgendeine Idee haben :) – Maartin1996

Antwort

0

Schnell Kommentar und zu Fuß durch

#include <iostream> 
#include <fstream> 
#include <string> 
using namespace std; 

using namespace std; Vermeiden Sie, während Sie lernen. Es kann zu einigen wirklich unangenehmen, schwer zu pinnenden Fehlern führen, da Ihre Funktionen stillschweigend durch Funktionen mit demselben Namen in der Standardbibliothek ersetzt werden.

const int buffer_size = 30; 

class Word 
{ 
    char name[buffer_size]; 

Da es sieht aus wie Sie verwenden dürfen std::string, warum es hier nicht benutzen?

public: 
    void setName() // Trying to get every word from a line 

Wirklich schlecht Name für eine Funktion, die anscheinend soll // Trying to get every word from a line

{ 
     string STRING; 
     ifstream infile; 
     infile.open("text.txt"); 
     while (!infile.eof()) // To get you all the lines. 
     { 
      getline(infile, STRING); // Saves the line in STRING. 
     } 

Nur wenige Dinge falsch hier. One ist das Epische Why is iostream::eof inside a loop condition considered wrong?

Nächste ist, während der Code liest jede Zeile, es tut nichts mit der Linie. STRING wird niemals irgendwo gespeichert.

Endlich in einer Klasse, die klingt, als ob sie ein einzelnes Wort enthalten und verwalten sollte, liest sie alle Wörter in der Datei. Es kann einen Fall geben, diese Funktion in eine statische Fabrik zu verwandeln, die eine std::vector von Words erzeugt.

 infile.close(); 
    } 
}; 

void write_record() 
{ 
    ofstream outFile; 
    outFile.open("binFILE.bin", ios::binary | ios::app); 

ios::app wird zu einer vorhandenen Datei hinzugefügt. Das klingt nicht wie in der Aufgabenbeschreibung beschrieben.

Word obj; 
    obj.setName(); 

Wir haben coverred bereits die Versäumnisse der Word Klasse.

outFile.write((char*) &obj, sizeof(obj)); 

Das Verspritzen eines Objekts in einen Stream, ohne ein Datenprotokoll zu definieren oder eine Serialisierung zu verwenden, ist gefährlich. Es macht die Datei nicht tragbar. Sie werden feststellen, dass einige Klassen, darunter vector und string, ihre Daten nicht enthalten. Wenn Sie eine Zeichenfolge in eine Datei schreiben, erhalten Sie möglicherweise nichts mehr als eine Zählung und eine Adresse, die mit hoher Wahrscheinlichkeit nicht gültig ist, wenn die Datei geladen wird.

In diesem Fall enthält das ganze Objekt ein Array von Zeichen und das sollte sauber in die Datei schreiben, aber es wird immer genau 30 Bytes schreiben und das ist vielleicht nicht das, was Sie wollen.

outFile.close(); 
} 

int main() 
{ 
    write_record(); 
    return 0; 
} 

Da es sich um Hausaufgaben Ich bin nicht diese Sauger für Sie zu schreiben, aber hier sind ein paar Vorschläge:

Read file line by line werden Sie auf die Datei-Reader gestartet. Ihr Fall ist einfacher, weil es in jeder Zeile nur ein Wort gibt. Dein Lehrer kann einen Curveball werfen und mehr Zeug in eine Linie einfügen, also solltest du es vielleicht testen.

Lesen Sie die Wörter aus der Datei in eine std::vector. vector wird Ihre Arbeit so einfach machen, dass Sie vielleicht Zeit für andere Hausaufgaben haben.

Eine sehr einfache Implementierung ist:

std::vector<std::string> words; 
while (getline(infile, STRING)) // To get you all the lines. 
{ 
    words.push_back(STRING); 
} 

Für die Datei wieder aus binär schreiben, I suggest going Pascal style. zuerst die Länge der Zeichenfolge in binären schreiben. Use a known, fixed width unsigned integer (keine negative Zeichenkette) und watch out for endian. Sobald die Länge geschrieben ist, schreibe nur die Anzahl der Zeichen, die du schreiben musst.

Endian Ignorieren, sollten Sie etwas wie dieses:

uint32_t length = word.length(); // length will always be 32 bits 
out.write((char*)&length, sizeof(length)); 
out.write(word.c_str(), length); 

Wenn Sie den Schriftsteller getan schreiben, eine Lesefunktion schreiben, so dass Sie, dass der Schreiber korrekt funktioniert testen. Testen Sie Ihren Code immer, und ich empfehle nichts zu schreiben, bis Sie wissen, wie Sie es testen werden. Sehr oft wird es bei einem Programm von der Testseite zuerst Probleme geben, bevor sie überhaupt eine Chance haben, anzufangen.

+0

Ich nahm unter Beratung Ihre Vorschläge. Außerdem habe ich verschiedene Ansätze ausprobiert. Da ich unter Linux bin, weiß ich nicht, wie ich meine .bin-Datei öffnen soll, damit ich den Inhalt der Datei sehen kann (nicht sicher, ob mein Programm jetzt funktioniert, aber vielleicht können Sie es sich ansehen) – Maartin1996

+0

Machen Sie eine Suche Mit welchem ​​Paketmanager auch immer Ihre Linux-Distribution für den "Hex-Editor" verwendet oder ob Ihr Lieblingseditor einen Hex-Modus enthält. Ein Hex-Editor ermöglicht es Ihnen, eine Datei zu öffnen und sie als Bytes dargestellt zu sehen. – user4581301