Seite 1 von 1
Zahlen aus Datei lesen klappt nicht
Verfasst: 23. April 2014 23:50
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
wobei n eine Gleitkommazahl ist, falsch. Weiß jemand, was ich ändern muß?
Re: Zahlen aus Datei lesen klappt nicht
Verfasst: 26. April 2014 08:53
von Christian81
Du schreibst die Daten mit QTextStream in die Datei und wunderst Dich dann, dass Du die Daten nicht mit QDataStream einlesen kannst.
Re: Zahlen aus Datei lesen klappt nicht
Verfasst: 26. April 2014 22:43
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.
Re: Zahlen aus Datei lesen klappt nicht
Verfasst: 26. April 2014 22:53
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
Re: Zahlen aus Datei lesen klappt nicht
Verfasst: 3. Mai 2014 22:38
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'
Re: Zahlen aus Datei lesen klappt nicht
Verfasst: 3. Mai 2014 22:47
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.
Re: Zahlen aus Datei lesen klappt nicht
Verfasst: 4. Mai 2014 08:41
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.
Re: Zahlen aus Datei lesen klappt nicht
Verfasst: 5. Mai 2014 13:44
von dolin93
Vielen Dank für Deine Hilfe!
Zeile 21 lautet
und Zeile 24
. 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.
Re: Zahlen aus Datei lesen klappt nicht
Verfasst: 5. Mai 2014 17:55
von bmann
Hi
in deinem Code
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
Re: Zahlen aus Datei lesen klappt nicht
Verfasst: 8. Mai 2014 22:30
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 );
}
Re: Zahlen aus Datei lesen klappt nicht
Verfasst: 8. Mai 2014 23:13
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.