Forum: PC-Programmierung Daten in einer Datei Schreiben und lesen


von gerbej s. (sgerbej)


Lesenswert?

Hallo zusammen!
ich bin neulinge in c++ und vesuche zwei classen Input und saveload 
zuschreiben; in input soll Funktionswerte(x und y),die ich später 
plotten möchte,ausgewertet. in zweite class saveload soll die Daten 
geschrieben bzw. gelesen werden und der Pfade soll über konsole 
eigegeben .
kann jamend mein Code kurz angucken und mir tipps geben wie ich das zum 
laufen krigen kann;

hier ist Project.h
1
truct XYpair{
2
  double x;
3
  double y;
4
  XYpair(double x, double y):x(x),y(y){}
5
};
6
7
class INPUT{
8
9
private:
10
  int psize;
11
  double xmin,xmax;
12
  int wahl;
13
  std::vector<XYpair> dptr;
14
public:
15
  void setvalue();
16
  std::vector<XYpair> Dataplot(int psize);
17
  int menu();
18
};
19
class Saveload{
20
private:
21
  ifstream idatei;
22
  ofstream odatei;
23
  std::vector<XYpair> Vp;
24
  char pfad [200];
25
public:
26
  void save(int n, std::vector<XYpair>);
27
  std::vector<XYpair> load();
28
};
29
#endif
Abschitt von project.cpp
1
std::vector<XYpair> INPUT::Dataplot(int psize){
2
  
3
  double xr=(double)(xmax-xmin)/psize;
4
  double X=xmin;
5
  int i;
6
  std::vector<XYpair> dptr;
7
  X=xmin;
8
  for(i=0; i<psize; i++){
9
    dptr.push_back(XYpair(X,sin(X)));
10
    X+=xr;
11
  }
12
  return dptr;
13
}
14
15
void Saveload::save(int n, std::vector<XYpair> v){
16
  
17
  std::vector<XYpair> Vp;
18
  int i;
19
  for(i=0;i<=n-1;i++){
20
    Vp[i]=v[i];
21
  }
22
  
23
  cout<< "Unter welchem Pfadname soll es gepeichert werden?"<< endl;
24
  cin>>pfad;
25
  idatei.open(pfad, ios::in | ios::binary);
26
  
27
  if(!idatei){cout <<"Fehler beim Öffnen neuer Datei"<<endl;}
28
  
29
  idatei.read(Vp, sizeof(Vp)/sizeof(Vp[0])); 
30
  
31
  idatei.close()
32
    }
33
34
std::vector<XYpair> Saveload:: load(){
35
  int n;
36
  cout<<"von welchem Pfad soll ausgelesen werden"<< endl;
37
  cin>>pfad;
38
  
39
  odatei.open(pfad, ios::out | ios::binary);
40
41
  if(!odatei){cout <<"Fehler beim Öffnen der Datei"<<endl;}
42
  std::vector<XYpair> ptr;
43
  odatei.write(Vp,size(n));
44
  for(i=0; i<n; i++)
45
    ptr[i]=Vp[i];
46
  odatei.close();
47
return ptr;
48
}
Abschitt von main.cpp
1
int main(){
2
  int Wahl;
3
  int psize=15;
4
  std::vector<XYpair> V;
5
  
6
NPUT fdata;
7
  Saveload pdata;
8
  Wahl=fdata.menu();
9
if(Wahl==1){
10
  fdata.setvalue();
11
  V=fdata.Dataplot(psize);
12
  pdata.save(psiz,V);
13
   }
14
else if(Wahl==2){
15
    
16
   V =pdata.load();
17
   for(int i=0; i<psize-1; i++){
18
      cout <<"V.x"<<V[i].x<<"V.y"<<V[i].y<<'\n';
19
    }
meine probleme sin  eigentlich beim Lesen und schreiben , ich habe da 
mehrere syntax Fehler.

ich bin für jeder Hilfe sehr dankbar .

Gruß
Seb

von Nico S. (nico22)


Lesenswert?

Wie wäre es, wenn du die Fehlermeldungen vom Compiler gleich 
mitkopierst?

von gerbej s. (sgerbej)


Lesenswert?

hier ist die Compilerfehler
1
g++ -c project.cpp
2
project.cpp: In member function ‘void Saveload::save(int, std::vector<XYpair>)’:
3
project.cpp:50:42: error: no matching function for call to ‘std::basic_ifstream<char>::read(std::vector<XYpair>&, unsigned int)’
4
project.cpp:50:42: note: candidate is:
5
/usr/include/c++/4.6/istream:467:7: note: std::basic_istream<_CharT, _Traits>& std::basic_istream<_CharT, _Traits>::read(std::basic_istream<_CharT, _Traits>::char_type*, std::streamsize) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::char_type = char, std::streamsize = int]
6
/usr/include/c++/4.6/istream:467:7: note:   no known conversion for argument 1 from ‘std::vector<XYpair>’ to ‘std::basic_istream<char>::char_type* {aka char*}’
7
project.cpp:53:2: error: expected ‘;’ before ‘}’ token
8
project.cpp: In member function ‘std::vector<XYpair> Saveload::load()’:
9
project.cpp:64:25: error: ‘size’ was not declared in this scope
10
project.cpp:65:7: error: ‘i’ was not declared in this scope
11
make: *** [project

von xgast (Gast)


Lesenswert?

Beitrag "GNU Libmatheval in C++ Programm anwenden"

1. std::vector direkt lesen oder schreiben geht nicht. Du musst jedes 
Element einzeln lesen/schreiben (und bei einem zusammengesetzten typ, 
z.B struct wieder die Elemente einzeln lesen/schreiben)
2. zeile 52 fehlt ein ;
3. size(n) evtl sizeof(n)?
4. i was not declared... compiler hat recht..
5. load und save namen sind vertauscht? load=write, save=read?

von Karl H. (kbuchegg)


Lesenswert?

Und warum du da in den Funktionen jedesmal den std::vector erst mal 
durch die Gegend kopierst, musst du mir auch erst mal erklären.

von Karl H. (kbuchegg)


Lesenswert?

Und noch ein Tipp:

Beim Speichern von Daten, ist es eine extrem gute Idee, wenn man vor die 
Daten erst mal rausschreibt, wieviele Daten denn überhaupt geschrieben 
werden.

Eine extrem gute Idee ist das deshalb, weil man dann beim Einlesen erst 
mal diese Anzahl einliest und dann weiß, wieviele Datensätze im File 
noch kommen werden.

Beim Schreiben einer Datei muss man sich in der Datei die Informationen 
reinschreiben, die später beim Lesen der Datei zur Steuerung des 
Lesevorgangs genutzt werden.

von Karl H. (kbuchegg)


Lesenswert?

1
idatei.open(pfad, ios::in | ios::binary);
2
  
3
  if(!idatei){cout <<"Fehler beim Öffnen neuer Datei"<<endl;}
4
  
5
  idatei.read(Vp, sizeof(Vp)/sizeof(Vp[0]));

ist ja schön, wenn du deinem Benutzer mitteilst, dass du die Datei nicht 
öffnen konntest. Nur: Auf eine nicht geöffnete Datei kann man auch nicht 
schreiben/lesen. D.h. du musst das natürlich auch berücksichtigen, dass 
du einen Fehler hattest und dass du deshalb nichts Schreiben lesen 
kannst.
(Und eventuell sollte das auch der Aufrufer der Funktion wissen, dass da 
was schief gelaufen ist, damit der dann wiederrum nicht einen 
fehlerhaften std::vector in die Auswertung weitergibt)

von gerbej s. (sgerbej)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Und warum du da in den Funktionen jedesmal den std::vector erst mal
> durch die Gegend kopierst, musst du mir auch erst mal erklären.

ich denke mal das ich die daten in eine Buffer erstmal schreibe .

Karl Heinz Buchegger schrieb:
> Und noch ein Tipp:
>
> Beim Speichern von Daten, ist es eine extrem gute Idee, wenn man vor die
> Daten erst mal rausschreibt, wieviele Daten denn überhaupt geschrieben
> werden.
>
> Eine extrem gute Idee ist das deshalb, weil man dann beim Einlesen erst
> mal diese Anzahl einliest und dann weiß, wieviele Datensätze im File
> noch kommen werden.
>
> Beim Schreiben einer Datei muss man sich in der Datei die Informationen
> reinschreiben, die später beim Lesen der Datei zur Steuerung des
> Lesevorgangs genutzt werden.

void Saveload::save(int n, std::vector<XYpair> v)
n ist die Anzhal der Byte der ich schreiben möchte

read() erwartet ein char* und frage mich wie kann ich die std::vector 
übergebe

von Karl H. (kbuchegg)


Lesenswert?

gerbej seb schrieb:
> Karl Heinz Buchegger schrieb:
>> Und warum du da in den Funktionen jedesmal den std::vector erst mal
>> durch die Gegend kopierst, musst du mir auch erst mal erklären.
>
> ich denke mal das ich die daten in eine Buffer erstmal schreibe .


Wozu?


>> Beim Schreiben einer Datei muss man sich in der Datei die Informationen
>> reinschreiben, die später beim Lesen der Datei zur Steuerung des
>> Lesevorgangs genutzt werden.
>
> void Saveload::save(int n, std::vector<XYpair> v)
> n ist die Anzhal der Byte der ich schreiben möchte

OK. Kann man so machen. Muss man aber nicht. Der std::vector weiß selber 
wie gross er ist. Du brauchst ihn nur 'fragen'. Dieselbe Information 
(nämlich die Anzahl der Wertpaare) 2 mal im System zu haben, ist immer 
ein 'Ask for trouble'. Alte Datenbankweisheit: Speichere dieselbe Info 
niemals 2 mal ab. Im besten Fall passiert nichts. Im schlimmsten Fall 
stimmen die beiden Angaben nicht überein. Welche der beiden stimmt denn 
dann?

Und rechne besser nicht damit, dass du immer den besten Fall vorliegen 
hast.

>
> read() erwartet ein char* und frage mich wie kann ich die std::vector
> übergebe

gar nicht.
Du liest 2 double ein (denn die hast du auch geschrieben), konstruierst 
daraus ein XYPair Objekt, welches du mit push_back an den std_vector 
anhängst.

Und genauso kannst du den std::vector nicht einfach in write 
hineingeben, sondern musst das Element für Element machen. Ein Element 
nach dem anderen aus dem std::vector herausholen und die Werte dieses 
Elements in die Datei schreiben.

Das hat aber xgast kurz vor 19:00 schon angemerkt.


Hast du denn kein C++ Buch?
Ich wiederhole es gerne nochmal: Online Tutorien sind kein Ersatz für 
ein ordentliches Buch!

von Karl H. (kbuchegg)


Lesenswert?

Und ehe du dich an binären Files versuchst, schlage ich vor, dass du 
erst mal ganz normale Text-Files erstellst und wieder einliest. Denn 
dann kannst du mit jedem ordinären Texteditor kontrollieren, ob das 
File, das du geschrieben hast auch wirklich in Ordnung ist. In deinem 
Stadium ist nichts schlimmer als Stochern im Nebel, weil du nicht weißt 
ob dein Einlese-Code falsch ist oder ob der Rausschreiben-Code schon 
eine ungültige Datei erzeugt hat.

von gerbej s. (sgerbej)


Lesenswert?

das zu mindest was mir der copmiler mitteilt
1
project.cpp:50:20: error: no matching function for call to ‘std::basic_ifstream<char>::read(std::vector<XYpair>&, int&)’
2
project.cpp:50:20: note: candidate is:
das read() ein parameter von typ char

von gerbej s. (sgerbej)


Lesenswert?

danke für deinen Vorschlag das werde ich jetzt versuchen normale 
Test-file zu erstellen

von Karl H. (kbuchegg)


Lesenswert?

1
#include <iostream>
2
#include <vector>
3
#include <string>
4
5
struct XYpair
6
{
7
  XYpair(double x, double y):x(x),y(y){}
8
9
  double x;
10
  double y;
11
};
12
13
14
class Saveload
15
{
16
  public:
17
    bool save( const std::vector<XYpair>& data );
18
    bool saveTo( const std::string& fileName, const std::vector<XYpair>& data );
19
20
    std::vector<XYpair> load();
21
    std::vector<XYpair> loadFrom( const std::string& fileName );
22
23
  private:
24
    std::string askForPath( const std::string& question );
25
};

1
#include <iostream>
2
#include <fstream>
3
#include <string>
4
#include "Plotter.h"
5
6
using namespace std;
7
8
////////////////////////////////////////////////////////////////////////
9
//
10
std::string Saveload::askForPath( const std::string& question )
11
{
12
  std::string pfad;
13
14
  cout << question << endl;
15
  cin >> pfad;
16
17
  return pfad;
18
}
19
20
////////////////////////////////////////////////////////////////////////
21
//
22
bool Saveload::save( const std::vector<XYpair>& data )
23
{
24
  std::string fileName = askForPath( "auf welche Datei soll geschrieben werden" );
25
  
26
  return saveTo( fileName, data );
27
}
28
29
////////////////////////////////////////////////////////////////////////
30
//
31
bool Saveload::saveTo( const std::string& fileName, const std::vector<XYpair>& data )
32
{
33
  ofstream outFile;
34
35
  outFile.open( fileName.data() );
36
  if( !outFile ) {
37
    cout << "Konnte Datei " << fileName << " nicht zum Schreiben öffnen" << endl;
38
    return false;
39
  }
40
41
  outFile << data.size() << "\n";
42
43
  for( size_t i = 0; i < data.size(); ++i )
44
    outFile << data[i].x << " " << data[i].y << "\n";
45
46
  outFile.close();
47
48
  return true;
49
}
50
  
51
////////////////////////////////////////////////////////////////////////
52
//
53
std::vector<XYpair> Saveload::load()
54
{
55
  std::string fileName = askForPath( "von welchem Pfad soll ausgelesen werden" );
56
57
  return loadFrom( fileName );
58
}
59
60
////////////////////////////////////////////////////////////////////////
61
//
62
std::vector<XYpair> Saveload::loadFrom( const std::string& fileName )
63
{
64
  ifstream inFile;
65
  std::vector<XYpair> result;
66
67
  inFile.open( fileName.data() );
68
  if( !inFile ) {
69
    cout << "Konnte Datei " << fileName << " nicht zum Schreiben öffnen" << endl;
70
    return result;
71
  }
72
73
  size_t size;
74
75
  inFile >> size;
76
  for( size_t i = 0; i < size; ++i ) {
77
    double x, y;
78
    inFile >> x >> y;
79
    result.push_back( XYpair( x, y ) );
80
  }
81
82
  inFile.close();
83
84
  return result;
85
}
86
87
// *********************************** //
88
void dumpData( const std::vector<XYpair>& data )
89
{
90
  for( size_t i = 0; i < data.size(); ++i )
91
    cout << i << ": " << data[i].x << " " << data[i].y << "\n";
92
}
93
94
int main()
95
{
96
  std::vector<XYpair> data;
97
  Saveload Filemanager;
98
99
  data.push_back( XYpair( 1.0, 1.0 ) );
100
  data.push_back( XYpair( 2.0, 3.0 ) );
101
  data.push_back( XYpair( 3.0, 2.0 ) );
102
  data.push_back( XYpair( 4.0, 0.0 ) );
103
104
  cout << "Originaldaten\n";
105
  dumpData( data );
106
107
  cout << "Saving to file\n";
108
  Filemanager.saveTo( "c:\\data.txt", data );
109
110
  cout << "Reading back from file\n";
111
  std::vector<XYpair> copy;
112
  copy = Filemanager.loadFrom( "c:\\data.txt" );
113
114
  cout << "This is, what I read from file\n";
115
  dumpData( copy );
116
117
  cout << "Now you can save the data\n";
118
  Filemanager.save( copy );
119
120
  return EXIT_SUCCESS;
121
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.