2016-06-28 7 views
-1

ich eine Datei mit <fstream> zu lesen und die Datei Zeilen wie diese enthält:einen bestimmten Teil einer Textdatei in C Lesen ++

Name=Cecil 
Age=34 
Born=London 
//etc. 

Aus Gründen der diesem Beispiel können sagen, ich möchte Weisen Sie 34 der Variablen int age zu. Das würde bedeuten, dass ich herausfinden muss, welche Zeile mit Age beginnt, und dann den Wert 34 nach dem Gleichheitszeichen extrahieren.

Später möchte ich diesen Wert im Programm ändern, und ersetzen Sie es in der Datei, so 34 würde zum Beispiel 35, also wieder, ich muss diesen bestimmten Teil der Datei finden und dort schreiben.

Es scheint wie eine grundlegende Aufgabe, aber ich konnte bisher keine guten Beispiele finden. Vielleicht wäre es besser, meine Daten als JSON oder XML zu speichern und zu diesem Zweck eine Bibliothek zu verwenden?

+1

Leser für 'ini' kann passen Zum Beispiel https://github.com/benhoyt/inih oder https://github.com/brofield/simpleini – sp2danny

+0

Das wäre genau das, was ich brauche, aber ich kämpfe mit der Installation. Ich bekomme immer den Fehler 'undefinierter Verweis auf' INIReader :: INIReader (std :: string) ''. Ich habe die INIReader.h- und die ini.h-Dateien in der Include-Bibliothek und die INIReader.cpp-Datei neben der main.cpp-Datei platziert. Ich benutze C :: B. Ich weiß nicht, was ich vermisse. – Letokteren

+0

kompilieren Sie tatsächlich und verknüpfen Sie mit 'INIReader.cpp' (siehe [hier] (http://www.cprogramming.com/compilingandlinking.html)) – sp2danny

Antwort

0

Da Ihre Daten sieht aus wie Key-Wert-Paare, also hier ist eine objektorientierte Art und Weise, dies zu tun:

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

struct DATA 
{ 
    struct PAIR 
    { 
      string m_szComponentSeparator; 
      string m_szKey; 
      string m_szValue; 
      PAIR() 
      { 
        m_szComponentSeparator = "="; 
      } 
      void Read(ifstream &_inFile) 
      { 
        string szLine; 
        _inFile >> szLine; 
        size_t pos = szLine.find(m_szComponentSeparator); 
        m_szKey = szLine.substr(0, pos); 
        m_szValue = szLine.substr(pos + 1); 
      } 
      void Write(ofstream &_outFile) 
      { 
        _outFile << m_szKey << m_szComponentSeparator << m_szValue << endl; 
      } 
      int To_int() 
      { 
        return atoi(m_szValue.c_str()); 
      } 
      void SetAs_int(int _iValue) 
      { 
        char szBuf[32] = {0}; 
        snprintf(szBuf, sizeof(szBuf), "%d", _iValue); 
        m_szValue = szBuf; 
      } 

    }; 

    PAIR m_stName; 
    PAIR m_stAge; 
    PAIR m_stBorn; 
    void Read(string _szFilepath) 
    { 
      ifstream inFile(_szFilepath.c_str()); 
      m_stName.Read(inFile); 
      m_stAge.Read(inFile); 
      m_stBorn.Read(inFile); 
    } 
    void Write(string _szFilepath) 
    { 
      ofstream outFile(_szFilepath.c_str()); 
      m_stName.Write(outFile); 
      m_stAge.Write(outFile); 
      m_stBorn.Write(outFile); 
    } 
    void Print() 
    { 
      cout << m_stName.m_szKey << m_stName.m_szComponentSeparator << m_stName.m_szValue << endl; 
      cout << m_stAge.m_szKey << m_stAge.m_szComponentSeparator << m_stAge.m_szValue << endl; 
      cout << m_stBorn.m_szKey << m_stBorn.m_szComponentSeparator << m_stBorn.m_szValue << endl; 
    } 
}; 
int main() 
{ 
    string szInputFile = "in.txt"; 
    string szOutputFile = "out.txt"; 

    DATA oData; 
    oData.Read(szInputFile); 
    oData.Print(); 

    int age = oData.m_stAge.To_int(); 
    age = 35; 
    oData.m_stAge.SetAs_int(age); 

    cout << "after modification:" << endl; 
    oData.Print(); 

    oData.Write(szOutputFile); 

    return 0; 
} 

//Output: 
Name=Cecil 
Age=34 
Born=London 
after modification 
Name=Cecil 
Age=35 
Born=London 
+0

Gibt es einen Grund für Down-Voting? – sameerkn

+0

Obwohl ich Ihren vollständigen Code noch nicht implementiert habe, haben Sie mir einige gute Ideen gegeben, wie Sie das Problem lösen können. Ich habe meine eigene Methode mit 'find()', 'substr()' und 'atoi()' erstellt. Es sieht so aus, als ob ich diese Funktionen benötigt hätte. (Ich weiß nicht, wer Sie gewählt hat.) – Letokteren

+0

Wahrscheinlich abgelehnt, weil reine Code-Antworten nicht gerade hilfreich sind. Es ist das alte * "Verteilen des Fisches" *. Eine wertvollere Antwort würde eine Begründung enthalten. Begründung ist wichtig, damit Sie wissen, wann guter Rat schlecht wird. – IInspectable

2

Das ist ein Grundbedürfnis, aber keine grundlegende Implementierung, da Dateien nur Byteströme sind und keine Struktur haben. Das bedeutet, dass Sie einen Algorithmus implementieren müssen, um die geschriebenen Daten zu interpretieren/analysieren. Sie sollten wissen, dass Sie etwas in einer Datei weder löschen noch einfügen können. Ich meine, es gibt keine einzige Operation, die den Trick macht, und das ist ein Problem in Ihrem Fall, wenn Sie 34 durch 7 ersetzen möchten, ist die Länge dieser Informationen anders und Sie möchten ein Zeichen löschen (unmöglich) und ersetzen Sie das andere (Das ist möglich); Die gleiche Argumentation beim Ersetzen von 34 durch 103. Aus diesem Grund sind Datenbanken für: Sie können strukturierte Informationen auf einfache Weise verwalten.

Ok, das bedeutet nicht, dass dies unmöglich ist, da Datenbanken Dateien verwenden. Kann sein, in erster Näherung können Sie: alle die Datei lesen und analysieren, um strukturierte Daten im Speicher, dann verwalten Sie diese Daten und schreiben Sie bei Bedarf die Daten in einer neuen Datei. Natürlich ist dies keine ernsthafte Implementierung, wenn Sie zu viele Daten haben.

1

Dies ist nur einige allgemeine Überlegungen als Antwort auf die letzte „Vielleicht wäre es besser, zu ... ":

Jede einfache Implementierung wird ein bisschen fragil, aber wenn Sie sehr gute Kontrolle über Eingabedatei haben, und das Risiko von möglichen Datenschaden stört Sie nicht zu viel (dh Schäden werden niedrig und leicht zu restaurieren/zu reparieren), können Sie sogar mit String - Ersatz davonkommen, nach "Age = 34 \ n" suchen und es durch "Age = 35 \ n" ersetzen (wenn es nur eine Age - Linie in der Datei, andernfalls müssen Sie zuerst die richtige Person finden) ... die ganze Datei zuerst in den Speicher lesen und dann nach dem Ersetzen zurückschreiben.

Wenn Sie JSON verwenden, erhalten Sie mehr Sicherheit über die Struktur (keine Chance, versehentlich "CarnAge = 34" anstelle von "Age = 34" zu ändern), doch JSON kann im Nur-Text-Editor bearbeitet werden (wenn Sie vorsichtig sind genug). Auch JSON ist eine sehr beliebte Möglichkeit, Daten mit Webdiensten auszutauschen. Und dieser Absatz gilt auch für XML, obwohl ich denke, dass JSON für Nicht-Programmierer etwas einfacher zu lernen ist. Also die "ini" würde tun, aber ich bevorzuge immer noch JSON.

Und schließlich, wenn das etwas ernster ist, wäre die Berücksichtigung einiger Datenbank sehr sinnvoll. Dies sind verifizierte Lösungen zum effektiven Speichern/Modifizieren/Abrufen von Daten, die mit Datei-E/A wesentlich effizienter sind als das Lesen/Schreiben ganzer Dateien (DB behandelt Dateien so, dass sie Inhalte durch Überschreiben nur von Teilen modifizieren können.) indem man Reserveflächen um den Computer herum hält und einen Mechanismus hat, um einen Teil einer Datei vollständig zu restrukturieren).Plus die meisten DBs sind ACID, so fügen Sie zusätzliche Robustheit zu Ihrer App "kostenlos". Sie können die Daten einfach nicht im Nur-Text-Format bearbeiten (Sie können aber trotzdem Daten in einigen Tabellen vorbereiten und über ein DB-Manager-Tool importieren).

Die einzigen Gründe, warum man eine gemeinsame DB vermeiden sollte - ich kann mir vorstellen - sind: 1) Leistung (in speziellen Fällen wird ein guter Programmierer die professionelle DB Engine übertreffen, aber die meiste Zeit ist es nicht den großen Aufwand wert) , 2) Projekt ist zu klein/Tutorial, also während die Integration zum Beispiel "sqlite" ist nicht so schwierig, nur das Lesen der ganzen Datei und Ersetzen der Zeichenfolge ist noch einfacher. Aber zum Beispiel schreibe ich meine C++ Projekte mit U ++ Framework, so SQL Zugabe wäre eine Brise von wenigen zusätzlichen Linien, keine große Mühe ...

+0

Vielen Dank für die gut durchdachte Antwort! Es wäre gut, eine Datenbank zu verwenden, aber das Projekt ist sehr klein und das Einrichten einer Datenbank ist nicht im Bereich. Ich denke, ich nehme Ihren Vorschlag, und wenn ich einen Wert ändern möchte, erzeuge ich einfach die ganze Datei mit der bearbeiteten Zeichenfolge neu. – Letokteren

0

versuchen Sie diese

ifstream ifs("e:\\file.txt"); 
vector<string> file;  
string temp; 

while(getline(ifs, temp)) 
{ 
    if(temp.compare(0,4,"Age=")==0) 
     temp.replace(0, sizeof("Age=125"),"Age=125"); 

     file.push_back(temp); 
} 
ifs.close(); 

ofstream ofs("e:\\file.txt"); 
for(auto begin = file.begin(), end = file.end(); begin!=end; begin++) 
    ofs << *begin << endl; 

ofs.close();