Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Mal wieder: Einlesen aus Datei

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 < [ 2 ] [ 3 ]
000
11.06.2006, 22:23 Uhr
Pler
Einer von Vielen
(Operator)


Hallo!
Ich habe die Frage vor einiger Zeit schon mal gestellt. Allerdings haben sich die Bedingungen etwas geändert und ausserdem kann ich das Thema nicht mehr finden...

Also, ich muss Zeilenweise einlesen. Der erste Wert in der Zeile ist immer ein unsigned int. Danach kommen ? viele doubles.
(Die Anzahl ist in einer Datei immer gleich, kann aber in ner anderen Datei auch mal anders sein.)
Das erste int soll in eine Varable und der Rest in einen vektor ( ein vektor je Zeile ).


Beispieldatei:

1            -4.4504   -202.0518    -39.2361    -23.1150     37.8346      6.0459
2           149.2849     -3.5735     41.0495     14.4723      5.2195     26.2954
7            -7.4950   -199.7807    -35.3384    -39.8919     40.8764     11.9973
8           -11.0422   -166.8778    -27.5438    -49.6058     40.5487     19.0599
11            -6.0458   -114.9060    -16.0019    -41.8272     37.0380     25.3123
12            15.8967    -64.4693     -2.0507    -19.8309     31.4064     30.0098
13            55.2340    -29.0726     12.3571      5.1285     24.5412     32.6511



Wie bekomme ich das nun am besten da rein?

Ich stelle mir das ungefähr so vor:


pseudo:

while( getline( in , tmpstring ) )
{
    myvector.push_back( tmpstring.split( "\s" );
    nNummer = myvector[0];
    myvector.loescheErstesElement;
}


So einfach ist es ja leider nicht.
Vielleicht kann das jmd. so ausm Ärmel schütteln. Würde mir sehr helfen.

Vielen Dank

Dieser Post wurde am 11.06.2006 um 22:25 Uhr von Pler editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
11.06.2006, 22:45 Uhr
Karldin Shinowa
Professional Noob


hmm:

1)das erste in unsigned int variable; neuen vector erstellen
2) solange zeichen "geten" bis man nicht mehr auf ein leerzeichen stößt.
3) solange in einen string zusammenzählen bis man auf ein leerzeichen trifft
4) den string mit atof() umwandeln und in den vector schieben
5) bei 2 wieder anfangen und sobald man auf ein "\n" stößt bei 1 anfangen

hab immoment keine Zeit das zu progen aber es sollte funktionieren
--
Ich will die Welt verbessern, doch Gott gibt mir nicht den Code.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
11.06.2006, 23:02 Uhr
~MartinF
Gast



C++:
#include <iostream>
#include <fstream>
#include <iterator>
#include <list>
#include <algorithm>

using namespace std;


struct out_
{
  int n;

  out_(int nr)
    : n(nr)
  {}

  void operator()(double* v) {
    for (int i=0; i<n; ++i)
      cout << v[i] << endl;
  }
};


int main()
{
  /**
   * @var n Anzahl Werte pro Zeile (ggf. vorher feststellen)
   */

  static const int n = 7;

  list<double*> v;

  /**
   * "datei" enthällt die geposteten Werte
   */

  ifstream is("datei");
  istream_iterator<double> ii(is);
  istream_iterator<double> eos;

  // Werte per istream_iterator auf ifstream einlesen
  while (ii != eos) {
    double* tmp = new double[n];
    for (int i=0; i<n; ++i) {
      tmp[i] = *ii++;
    }
    v.push_back(tmp);
  }

  // Werte ausgeben
  out_ o(n);
  for_each(v.begin(), v.end(), o);

  // Allokierten Speicher freigeben
  typedef list<double*>::iterator iter;
  for (iter i=v.begin(); i!=v.end(); ++i)
    delete[] *i;
}

 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
11.06.2006, 23:18 Uhr
Karldin Shinowa
Professional Noob


Hab doch Zeit Meine Version ist wohl unschöner und wahrscheinlich fehlerhaft


C++:
fstream File("text.txt");

vector<unsigned int> ints;
vector< vector<float>  > werte;

while(!File.eof())
{
   char cTemp='';
   string sTemp="";
   bool exit=false;
  

   while(true)
   {
      cTemp=File.get();
      if(cTemp=' ') break;
      sTemp+=cTemp;
   }
   ints.push_back(atoi(sTemp));

   vector<float> v;

   while(true)
   {
      while(true)
      {
         cTemp=File.get();
         if(cTemp!=' ') break;
         if(cTemp=='\n') exit=true;
        
      }

      sTemp="";

      while(true)
      {
          if(exit==true) break;
          cTemp=File.get();
          if(cTemp==' ') break;
          if(cTemp=='\n') exit=true;
          sTemp+=cTemp;
      }
      if(exit==true) break;
      
      v.push_back(atof(sTemp));
   }
   werte.push_back(v);
}


--
Ich will die Welt verbessern, doch Gott gibt mir nicht den Code.

Dieser Post wurde am 11.06.2006 um 23:20 Uhr von Karldin Shinowa editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
11.06.2006, 23:37 Uhr
Pler
Einer von Vielen
(Operator)


Oh, vielen Dank für eure ausführlichen Lösungsvorschläge!
Aber so was ähnliches hab ich auch schon geschrieben. Allerdings für Versionen von der Datei, die etwas komplizierter sind. Das Einlesen dauert dann Stunden....
(Die Datei kann schon mal 10MB groß sein und dann können das auch mehrere sein.)
Meine Hoffnung war, dass das etwas einfacher und performanter geht.
Es muss doch möglich sein, dass man das mehr oder weniger direkt in den vector reinbekommt. Ohne einzeln nach Leerzeichen zu suchen und so....

Aber ich werde mir das von euch morgen noch mal in Ruhe durchschaun und bei mir nachsehen, ob ich da was verbessern kann.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
12.06.2006, 00:13 Uhr
Hans
Library Walker
(Operator)


Hi,

dann bau Dir doch mal eine Testdatei von ... 10 oder auch 100 KB, (sofern Du die nicht schon hast) und lass den Lesevorgang von einem Profiler überwachen. Damit sollte sich der Performance-Engpass finden lassen, und dann kann man sich überlegen, wie man den beseitigt.

Hans
--
Man muss nicht alles wissen, aber man sollte wissen, wo es steht. Zum Beispiel hier: Nachdenkseiten oder Infoportal Globalisierung.

Dieser Post wurde am 12.06.2006 um 00:22 Uhr von Hans editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
12.06.2006, 01:06 Uhr
Spacelord
Hoffnungsloser Fall


Grossartig schneller als mit dem istream_iterator von MartinF wirst du es mit Standardmitteln wohl nicht hinbekommen.

PS: Dein Performanceproblem wird eher in den "Vergrösserungen" des Vectors liegen.Dann wird alles mehrmals komplett umkopiert ....nimm ne Liste und wenn du alles eingelesen hast erzeugst du nen vector mit den begin und end iteratoren der liste.

Gruss Spacelord
--
.....Ich mach jetzt nämlich mein Jodeldiplom.Dann hab ich endlich was Eigenes.

Dieser Post wurde am 12.06.2006 um 01:10 Uhr von Spacelord editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
12.06.2006, 07:42 Uhr
Pler
Einer von Vielen
(Operator)


ok, ich werd da mal schauen. Danke
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
12.06.2006, 09:17 Uhr
(un)wissender
Niveauwart


Also ich würde es so machen:


C++:
#include <algorithm>
#include <iterator>
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

struct Line
{
    unsigned _number;
    std::vector<double> _values;
};

std::ostream& operator<<(std::ostream& out, Line const& line);

int main()
{
    std::ifstream in("test.txt");
    std::vector<Line> lines;
    std::string line;
    std::stringstream formater;
    std::size_t reserve = 0;
    while(in && !in.eof())
    {
        std::getline(in, line);
        formater << line;
        lines.resize(lines.size() + 1);
        formater >> lines.back()._number;
        lines.back()._values.reserve(reserve);
        while(formater && !formater.eof())
        {
            double v;
            formater >> v;
            lines.back()._values.push_back(v);
        }    
        formater.clear();
        reserve = lines.back()._values.size();
    }  
    std::copy(lines.begin(), lines.end(),
        std::ostream_iterator<Line>(std::cout, "\n"));  
}

std::ostream& operator<<(std::ostream& out, Line const& line)
{
    out << line._number << ' ';
    std::copy(line._values.begin(), line._values.end(),
        std::ostream_iterator<double>(out, " "));  
    return out;
}



Misst du die Performance? Mich würde interessieren, welche Version die schnellste ist.
Ok, hängt natürlich auch immer von der lokalen Version der C++-Standardbibliothek ab.
--
Wer früher stirbt ist länger tot.

Dieser Post wurde am 12.06.2006 um 09:42 Uhr von (un)wissender editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
009
12.06.2006, 11:10 Uhr
(un)wissender
Niveauwart


Also, für 17mb wird unter 20 Sekunden gebraucht bei mir. Habe AthlonXP 1800+ mit 512 Ram.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 < [ 2 ] [ 3 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: