Zahlen aus Datei lesen klappt nicht

Du bist neu in der Welt von C++? Dann schau hier herein!
Antworten
dolin93
Beiträge: 45
Registriert: 5. Mai 2012 21:35

Zahlen aus Datei lesen klappt nicht

Beitrag von dolin93 »

Hallo,
nach dem Lesen von Kapitel 8 von "Foundations of Qt Development", das den Umgang mit Files, Streams und XML behandelt, wollte ich aus Dateien lesen, in die ich mit einem gewöhnlichen C++Programm geschrieben habe. Das Auslesen aus einer Textdatei hatte geklappt. Die angehängte binäre Datei Zahlen.dat, in der sich Gleitkommazahlen befinden, konnte ich zwar öffnen, aber nach Hinzufügen des Codes zum Auslesen erhielt ich die Fehlermeldung
/home/hans/Dokumente/Qt_Beispiele/FileExercise1-build-desktop-Qt_4_8_1_in_Pfad__System__Release/../FileExercise1/main.cpp:54: Fehler:could not convert 'fin.QDataStream::operator>>((* & n))' from 'QDataStream' to 'bool'
.Demnach ist

Code: Alles auswählen

QDataStream fin( &file );
  while(fin>>n)
wobei n eine Gleitkommazahl ist, falsch. Weiß jemand, was ich ändern muß?
Dateianhänge
Zahlen.dat.zip
(785 Bytes) 598-mal heruntergeladen
FileExercise1.zip
(3.36 KiB) 608-mal heruntergeladen
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Zahlen aus Datei lesen klappt nicht

Beitrag von Christian81 »

Du schreibst die Daten mit QTextStream in die Datei und wunderst Dich dann, dass Du die Daten nicht mit QDataStream einlesen kannst.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
dolin93
Beiträge: 45
Registriert: 5. Mai 2012 21:35

Re: Zahlen aus Datei lesen klappt nicht

Beitrag von dolin93 »

Vielen Dank für Deine Antwort!
Anfangs hatte ich mit diesem Programm und eben mit QTextStream etwas in eine Datei geschrieben und hernach wieder erfolgreich ausgelesen. Später habe ich dieses Programm leicht verändert und wieder mit QTextStream aus einer mit einem gewöhnlichen C++Programm beschriebenen Textdatei gelesen. Aber mit QDataStream aus der Datei Zahlen.dat zu lesen, in der sich ausschließlich Gleitkommazahlen befinden, die mit einem gewöhlichen C++Programm hineingeschrieben wurden, hat dann leider nicht geklappt. Ich habe auch schon in einem Qt-Programm mit der C++Vorgehenweise aus Zahlen.dat gelesen, aber lieber wäre mir, wenn ich es mit QDataStream auch könnte.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Zahlen aus Datei lesen klappt nicht

Beitrag von Christian81 »

Vielleicht solltest Du Dich noch einmal mit dem Sinn von QDataStream auseinander zu setzen:
Doku hat geschrieben: The QDataStream class provides serialization of binary data to a QIODevice.

A data stream is a binary stream of encoded information which is 100% independent of the host computer's operating system, CPU or byte order. For example, a data stream that is written by a PC under Windows can be read by a Sun SPARC running Solaris.

You can also use a data stream to read/write raw unencoded binary data. If you want a "parsing" input stream, see QTextStream.

The QDataStream class implements the serialization of C++'s basic data types, like char, short, int, char *, etc. Serialization of more complex data is accomplished by breaking up the data into primitive units.
--> http://qt-project.org/doc/qt-4.8/qdatastream.html
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
dolin93
Beiträge: 45
Registriert: 5. Mai 2012 21:35

Re: Zahlen aus Datei lesen klappt nicht

Beitrag von dolin93 »

Vielen Dank für Deine Hinweise!
In einer QtKonsolenanwendung hat das Auslesen aus der Datei "Zahlen.dat", gut geklappt mit

Code: Alles auswählen

void Read1(QString name2 )
{ double n;

  QFile file(name2);
  if( !file.open( QIODevice::ReadOnly ))
   {   qDebug()<<"Datei existiert nicht.";
    return;
   }
  qDebug()<<"offfffen";
  int i=0;
  std::ifstream fin("C:/Zahlen.dat",std::ios::in);
  while(fin>>n)
  { std::cout<<"  "<<n;
      i++;
      if(i%19==0)
      {std::cout<<" "<<std::endl;}
  }
  file.close();
  }
aber mit dieser Vorgehensweise geht es in einem TableView/Model-Programm verständlicherweise nicht. Mit

Code: Alles auswählen

qreal a[52][19];
qreal n;

  QFile file("C:/Zahlen.dat");
  file.open( QIODevice::ReadOnly);
  QDataStream in( &file );
  int i=0, j=0;
  while(in>>n)
  { a[i][j]=n;
      i++;
      if(i%19==0)
      {j++;
       i=0;
      }
  }
  file.close();
  }
erhalte ich jedoch die Fehlermeldungen
/home/hans/Dokumente/Qt_Beispiele/MulModel3-build-desktop-Qt_4_8_1_in_Pfad__System__Release/../MulModel3/dialog.cpp:21: Fehler:'file' does not name a type
und
/home/hans/Dokumente/Qt_Beispiele/MulModel3-build-desktop-Qt_4_8_1_in_Pfad__System__Release/../MulModel3/dialog.cpp:24: Fehler:expected unqualified-id before 'while'
dolin93
Beiträge: 45
Registriert: 5. Mai 2012 21:35

Re: Zahlen aus Datei lesen klappt nicht

Beitrag von dolin93 »

Vielen Dank für Deine Hinweise!
In einer QtKonsolenanwendung hat das Auslesen aus der Datei "Zahlen.dat", gut geklappt mit

Code: Alles auswählen

void Read1(QString name2 )
{ double n;

  QFile file(name2);
  if( !file.open( QIODevice::ReadOnly ))
   {   qDebug()<<"Datei existiert nicht.";
    return;
   }
  qDebug()<<"offfffen";
  int i=0;
  std::ifstream fin("C:/Zahlen.dat",std::ios::in);
  while(fin>>n)
  { std::cout<<"  "<<n;
      i++;
      if(i%19==0)
      {std::cout<<" "<<std::endl;}
  }
  file.close();
  }
aber mit dieser Vorgehensweise geht es in einem TableView/Model-Programm verständlicherweise nicht. Mit

Code: Alles auswählen

qreal a[52][19];
qreal n;

  QFile file("C:/Zahlen.dat");
  file.open( QIODevice::ReadOnly);
  QDataStream in( &file );
  int i=0, j=0;
  while(in>>n)
  { a[i][j]=n;
      i++;
      if(i%19==0)
      {j++;
       i=0;
      }
  }
  file.close();
  }
erhalte ich jedoch die Fehlermeldungen
/home/hans/Dokumente/Qt_Beispiele/MulModel3-build-desktop-Qt_4_8_1_in_Pfad__System__Release/../MulModel3/dialog.cpp:21: Fehler:'file' does not name a type
und
/home/hans/Dokumente/Qt_Beispiele/MulModel3-build-desktop-Qt_4_8_1_in_Pfad__System__Release/../MulModel3/dialog.cpp:24: Fehler:expected unqualified-id before 'while'
. Für den Fall, daß Du weißt, welche Änderungen ich vornehmen muß, hätte ich die Bitte, daß Du mir diese mitteilst.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: Zahlen aus Datei lesen klappt nicht

Beitrag von Christian81 »

Waru sollte man in einer Qt-Anwendung nicht mit std::ifstream einlesen können?
Wenn man jetzt noch wüsste wo Zeile 21 ist wäre ja evtl. zu helfen.
Anstatt statischer Array solltest du std::vector<> oder QVector<> benutzen. Ich verschieb das mal nach C++ Grundlagen denn die Probleme sind keine C++/Qt - Probleme sondern wohl eher grundlegenderer Natur.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
dolin93
Beiträge: 45
Registriert: 5. Mai 2012 21:35

Re: Zahlen aus Datei lesen klappt nicht

Beitrag von dolin93 »

Vielen Dank für Deine Hilfe!
Zeile 21 lautet

Code: Alles auswählen

  file.open( QIODevice::ReadOnly);
und Zeile 24

Code: Alles auswählen

while(in>>n)
. Den angegebenen Code aus dem Konsolenprogramm hatte ich anfangs in dieses Programm übernommen, was zu 3 Fehlermeldungen führte, die mich aber nicht überraschten (qDebug.....). Als ich den Code auf das Nötigste reduzierte, erhielt ich immer noch eine Fehlermeldung, was mich ebenso verwunderte wie die 2 Fehlermeldungen zu den Zeilen 21 und 24.
bmann
Beiträge: 14
Registriert: 22. Juni 2006 22:27
Wohnort: Dortmund

Re: Zahlen aus Datei lesen klappt nicht

Beitrag von bmann »

Hi

in deinem Code

Code: Alles auswählen

QDataStream fin( &file );
  while(fin>>n)
tust du eigentlich zwei Dinge:
1. Lese aus Stream "fin" den Wert n (was immer das auch ist, das hast du uns nicht gesagt. Vermutlich ist n ein int, dann wird ein binäres Integer, also i.d.R. 4 bytes geelesen)
2. Wiederhole dies so lange, bis "fin>>n" false zurückgibt.

Teil 1 ist dabei Ok. Teil 2 dagegen macht keinen Sinn, da "fin>>n" kein bool zurückgibt, sondern eine QDataStream Referenz und dieser lässt sich nicht in einen bool casten. Also etwas in der Art "if (fin)" macht keinen Sinn ("while (fin>>n" ist das gleiche).

Wenn du dagegen

Code: Alles auswählen

QDataStream fin( &file );
while(!fin.atEnd()) { fin >> n; }
machst, sollte es gehen.

Ob das allerdings Sinn macht ist eine andere Frage: Es werden dann so lange Werte gelesen, bis der Stream am Ende der Datei ist. n hat also als Wert das, was am Ende der Datei steht, alle Werte davor wurden überschrieben.

Mit std::ifstream funktioniert deine Variante, weil dein ifstream Unterstützung für diesen Ansatz mitbringt, genauer: Der ifstream lässt sich in void* casten, was sich wiederum in ein bool casten lässt. QDataStream erlaubt das nicht.

@Christian81: Der Code compiled erst gar nicht, dass ein Binärwert aus einer Textdatei ausgelesen wird hat damit nichts zu tun. Es ist allerdings natürlich korrekt, dass std::ifstream und QDataStream eine (ggf. teilweise) unterschiedliche Serialisierung verwenden. Das eine mit dem anderen zu lesen muss nicht immer funktionieren (bei ints sollte es jedoch gehen, floats/doubles sind ein Thema für sich). QDataStream und QTextStream zu mischen wird dagegen nicht ohne weitere Arbeiten funktionieren.

Gruß
Andi
dolin93
Beiträge: 45
Registriert: 5. Mai 2012 21:35

Re: Zahlen aus Datei lesen klappt nicht

Beitrag von dolin93 »

Vielen Dank!
Das Lesen aus der Datei Zahlen.dat, in der sich Gleitkommazahlen befinden klappt jetzt. Aber der Inhalt wird nur äußerst langsam und träge in einem TableView dargestellt. Eigentlich wollte ich das Programm so erweitern, daß ich den Inhalt schnell editieren kann. Aber bei dieser Trägheit scheint es nicht sinnvoll zu sein. Zusätzlich wird die Zahlen.dat auch über die Konsole ausgegeben, was äußerst schell erfolgt.

Code: Alles auswählen

#include "dialog.h"
#include <cmath>
#include <QCoreApplication>
#include <QFile>
#include <QString>
#include <QDebug>
#include <iostream>
#include <fstream>
float a[55][19];
double n;
Dialog::Dialog( int rows, int columns, QObject *parent ) : QAbstractTableModel( parent )
{
  m_rows = rows;
  m_columns = columns;
}
//void Dialog::Read1(QString name2 )
//{


 // }

int Dialog::rowCount( const QModelIndex &parent ) const
{
  return m_rows;
}

int Dialog::columnCount( const QModelIndex &parent ) const
{
  return m_columns;
}

Qt::ItemFlags Dialog::flags( const QModelIndex &index ) const
{
  return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
}

QVariant Dialog::data( const QModelIndex &index, int role ) const
{
  QFile file("/home/hans/Zahlen.dat");
  if( !file.open( QIODevice::ReadOnly ))
   {   qDebug()<<"Datei existiert nicht.";
    return false;
   }
  qDebug()<<"offfffen";
  int i=0, j=0;
  std::ifstream fin("/home/hans/Zahlen.dat",std::ios::in);
  while(fin>>n)
  { a[i][j]=n;
    std::cout<<"  "<<n;
      j++;
      if(j%19==0)
      {i++;
       j=0;
      std::cout<<" "<<std::endl;
      }
  }
  file.close();
  switch( role )
  {
  case Qt::DisplayRole:
       return (a[index.row()][index.column()]);
  case Qt::ToolTipRole:
    return QString( "%1 x %2" ).arg( index.row()+1 ).arg( index.column()+1 );

  default:
    return QVariant();
  }
}

QVariant Dialog::headerData( int section, Qt::Orientation orientation, int role ) const
{
  if( role != Qt::DisplayRole )
    return QVariant();

  return QString::number( section+1 );
}
bmann
Beiträge: 14
Registriert: 22. Juni 2006 22:27
Wohnort: Dortmund

Re: Zahlen aus Datei lesen klappt nicht

Beitrag von bmann »

Das Auslesen der Datei in data() ist eine *ganz* schlechte Idee. Du wirst die Datei woanders lesen müssen und dir dann die Werte speichern müssen.

QAbstractTableModel::data() wird aufgerufen wann immer "etwas" für eine Zelle in der Tabelle benötigt wird, also z.B. der Inhalt der Tablle (die Zahl die du ausgibst), die Schriftart, der Hintergrund, ..., jeweils abhängig vom "role" Parameter. Normalerweise also mehrmals für jede Zelle.

Dein Code liest dort nun *jedesmal* die Datei komplett ein und gibt dann höchstens einen Wert zurück (genau einen wenn role==DisplayRole, gar keinen für alle anderen roles).

Mache das ganze lieber (z.B.) im Konstruktor und gebe den Wert in data() nur zurück.
Antworten