zeilen aus Textdatei löschen

callas

Grünschnabel
Hallo,
ich hab ein Problem , nämlich habe ich eine mitarbeiterliste erstellt und lese die daten mit einem ofstream in eine Textdatei ein.
Wenn ich die daten wieder ausgeben lasse aus der Textdatei, dann wird der letzte beitrag immer doppel ausgegeben.
vll kann mir ja jemand sagen wieso und schreiben, was ich verändern muss..


unsigned int getFileSize(const char *file_name)
{
std::ifstream file(file_name);
file.seekg(0,std::ios::end);
return file.tellg();
}

std::ifstream& load(std::ifstream& in, std::string& val)
{
in >> val; // >> "\t";
}

std::string namee, vorname, alter, strasse, hausnummer, plz, wohnort;
std::ifstream infile;
infile.open("namen.txt", std::ios::in);
if (!infile)
{
std::cerr << "Couldn't open file \n";
}
int i = 1;
iter = name.begin();
while (infile.good())
{
load(infile, namee);
load(infile, vorname);
load(infile, alter);
load(infile, strasse);
load(infile, hausnummer);
load(infile, plz);
load(infile, wohnort);

std::cout << i << "\n";
std::cout << "Name : " << namee << "\n";
std::cout << "Vorname : " << vorname << "\n";
std::cout << "Geburtsdatum : " << alter << "\n";
std::cout << "Strasse : " << strasse << " \n";
std::cout << "Hausnummer : " << hausnummer << "\n";
std::cout << "Postleitzahl : " << plz << "\n";
std::cout << "Wohnort : " << wohnort << "\n\n";
++i;
std::cout << getFileSize("namen.txt") << "\n";
//std::cout << "Groesse der Multimap : " << name.size() << "\n";
}
//}while (infile.eof());
//}while (!infile.good());
infile.close();
infile.clear();
break;
 
achso, ich habe was vergessen.
ich dachte mir, das ich einfach den letzten eintrag immer löschen könnte ( der der doppelt ausgegeben wird),
also sicherlich ist es besser vll auch einfacher wenn man einfach den fehler im code sucht, warum genau der letzte eintrag zweimal ausgegeben wird..
 
Ohh man. Das ist so ganz schlimmer Stil:
C++:
 unsigned int getFileSize(const char *file_name)
{
std::ifstream file(file_name);
file.seekg(0,std::ios::end);
return file.tellg();
}
Hier muss unnötig implizit gecastet werden und unsigned int ist hier sogar unpassend. Besser wäre std::streamsize. Dann wäre hier direktes Springen ans Dateiende auch besser!

C++:
 std::ifstream& load(std::ifstream& in, std::string& val)
{
	in >> val; // >> "\t";
}
Diese Funkion ist nicht sonderlich nützlich, aber nugut.
Fehler: Es fehlt das return.
Verbesserung:
C++:
std::istream& read_sep(std::istream& in, std::string& data, const char sep = '\t')
{ return in >> val >> sep; }
Noch besser => Weglassen!

=>
C++:
struct user
{
    std::pair<std::string, std::string> name; // prename, name
    unsigned char age; // age
    std::pair<std::string, unsigned char> street; // street name, street number
    std::pair<unsigned short, std::string> city; // postal code, city name

    friend std::istream& operator>>(std::istream& in, user& data)
    { 
        // format: name, prename (age)|street|city
        char seperator;
        std::getline(in, data.name.second, ',');
        std::getline(in, data.name.first, '(');
        return ((in >> data.age).ignore(2) >> data.street.first >> data.street.second).ignore() >> data.city.first >> data.city.second;
    }    

    friend std::ostream& operator<<(std::ostream& out, user const& data)
    {
        return out    << data.name.second << ", " << data.name.first << '(' << data.age << ")\n" 
                    << data.street.first << " " << data.street.second << "\n"
                    << data.city.first << " " << data.city.second;
    }
};
So hast du die Ausgabe und Eingabe für die Standardströme bereitgestellt. Dann noch schnell das Einlesen und Ausgeben, was jetzt ganz einfach ist:
C++:
int main()
{
    std::ifstream file_stream("namen.txt");

    if (!infile) { std::cerr << "Could not open database!" << std::endl; return 1; }

    std::vector<user> data(std::istream_iterator<user>(file_stream), std::istream_iterator<user>());
    std::copy(data.begin(), data.end(), std::ostream_iterator<user>(std::cout, "\n");
}
... fertig.
Dateiaufbau:
Code:
Mustermann, Hans (40)|Musterstraße 89|12345 Musterstadt
Mustermann, Hans (40)|Musterstraße 89|12345 Musterstadt
Mustermann, Hans (40)|Musterstraße 89|12345 Musterstadt
 
jo, vielen dank.
ich gucke mir das morgen auf arbeit genauer an.
ich programmiere erst seit knapp 7 monaten, deshalb der schlechte stil....
könnt ich nich anstatt nem struct gleich ne klasse machen?
 
Nun das ist der Fehler, den viele Machen. Was ist denn anders an einer Klasse und einer Struct? Nix! Naja gut doch etwas. Standardmäßig ist die sichtbarkeit von struct public, von class private. Das war es auch schon!
 
naja ich weiß das es für die leute bei mir auf arbeit einen entscheidenden unterschied gibt , aber ich weiß nicht mehr welchen.
wie gesagt bin noch ein noop mehr oder weniger.
aber deshalb sehen die das auch nicht gerne wenn ich das dann benutze..
 
Nichts ;) Das ist ein Template (std::istream_iterator) und das Template wird mit user anstelle des Platzhalters compiliert (so vereinfacht gesagt). <user> sagt nur das das Template die Klasse user nutzen soll ;)
 
achso alles klar.
bei mir hat er beim compilieren nämlich genau in der zeile 5 fehler...
aber ich habe das ganze problem auch schon anders gelöst jetzt..
nur stehe ich im moment wieder vor einem neuen problem , nämlich wie ich sage
lösche in einem string ab position x bis zum nächsten newline....
Code:
txt.erase(find, ?);

also ich weiß halt nicht wie ich sage bis zum nächsten newline....
 
Zurück