[sloved]QString Zerlegen und im Array Speichern

Alles rund um die Programmierung mit Qt
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

steht doch alles da:

Code: Alles auswählen

uses local type 
Die Struktur muss global definiert sein - also in einem Header.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
jd
Beiträge: 130
Registriert: 22. Januar 2008 17:55

Beitrag von jd »

Hallo, also das läuft jetzt alles und sogar fehlerfrei :). Ich bedanke mich bei allen dir hier so tapfer durchgehalten haben :).

Ich hätte nur noch ein kleines Anliegen, und zwar was könnte ich an meinem Code besser machen... Möchte mich halt auch gerne an gewisse regeln halten damit auch alles sauber ist.

MeinWindow.h

Code: Alles auswählen

#ifndef MAINWINDOW_H_
#define MAINWINDOW_H_
#define GLOBAL
#include <QtGui>
#include "../../build/ui_MainWindow.h"

class CMainWindow : public QMainWindow, private Ui::MainWindow {
	Q_OBJECT
	public:
		CMainWindow();
		~CMainWindow();
	private:
		struct SHardDrive {
			QString filesystem;
			QString size;
			QString used;
			QString avail;
			QString usedPercent;
			QString mountPoint;
		};
		GLOBAL QList<SHardDrive> disk;
		void calculateDiskSpace();
};

#endif /*MAINWINDOW_H_*/
MainWindow.cpp

Code: Alles auswählen

#include "MainWindow.h"
#include "../DialogAbout/DialogAbout.h"
#include </usr/include/stdio.h>
#include <QFile>

CMainWindow::CMainWindow() {
	setupUi(this);

	connect(actionClose, SIGNAL( triggered( bool ) ),
			qApp, SLOT( quit() ));

	calculateDiskSpace();
}

CMainWindow::~CMainWindow() {}

void CMainWindow::calculateDiskSpace() {

	struct SHardDrive hdd;

	QString cmd("df -h | grep /dev/");
	FILE *infile = popen( QFile::encodeName(cmd).data(), "r" );
	if (infile == NULL) {
		QMessageBox::warning(0, tr("Error"), tr("Failed to parse command.\n"));
		return;
	}

	QFile file;
	if (!file.open(infile, QIODevice::ReadOnly)) {
		QMessageBox::warning(0, tr("Error"), tr("Failed to open file.\n"));
		return;
	}

	QTextStream in(&file);
	QString line;

	while (!in.atEnd()) {
		line = in.readLine();
		QStringList list;
		list = line.split(QRegExp("\\s+"), QString::SkipEmptyParts);

		hdd.filesystem = list[0];
		hdd.size = list[1];
		hdd.used = list[2];
		hdd.avail = list[3];
		hdd.usedPercent = list[4];
		hdd.mountPoint = list[5];

		disk.append(hdd);
	}

	/** Das wird noch in eine Schleife gepackt */
	labelDiskSpace->setText(disk[0].filesystem);

	QRegExp rx("%");
	QString tmp = disk[0].usedPercent.replace(rx, "");

	int x = tmp.toInt();
	int y = 16;

	QSize newSize(x, y);
	frameDrive1->resize(newSize);
	frameDrive1->setStyleSheet("background-color: green;");

	labelDiskSpace->adjustSize();
}
macman
Beiträge: 1738
Registriert: 15. Juni 2005 13:33
Wohnort: Gütersloh
Kontaktdaten:

Beitrag von macman »

Geh es mal anders an:

Code: Alles auswählen

//-- Das hier in den Header
struct SHardDrive {
		QString filesystem;
		QString size;
		QString used;
		QString avail;
		QString usedPercent;
		QString mountPoint;
	};

	QList<SHardDrive*> daten;
//--

SHardDrive* hdd=NULL;
while (!in.atEnd()) {
		line = in.readLine();
		QStringList list;
		list = line.split(QRegExp("\\s+"), QString::SkipEmptyParts);

		hdd = new SHardDrive;
		daten.append(hdd);
		hdd->filesystem = list[0];
		hdd->size = list[1];
		hdd->used = list[2];
		hdd->avail = list[3];
		hdd->usedPercent = list[4];
		hdd->mountPoint = list[5];
	}
Nicht vergessen die Strukturen im Destruktor zu löschen.

[edit]Ups, hatte sich schon erledigt :-)
Die deutsche Schriftsprache ist case-sensitive. Außerdem gibt es eine Interpunktionsnorm. Wenn manch einer seine Programme genauso schlampig schreibt, wie sein Posting hier, dann sollte er es lieber bleiben lassen.
jd
Beiträge: 130
Registriert: 22. Januar 2008 17:55

Beitrag von jd »

Danke, habe das jetzt abgeändert. Ich habe mein Programm mal durch den Debugger gejagt, der sagt mir immer:
ASSERT failure in QList<T>::operator[]: "index out of range", file /usr/include/qt4/QtCore/qlist.h, line 392
Und wenn ich das Programm normal starte kommt die Meldung 1x von 20 Starts.

Was er noch sagt, ist:
mi_cmd_var_create: unable to create variable object
Wie gehe ich denn da jetzt ran um den Bug zu fixen?

Liegt das daran das ich beim Programm im Debug-Modus starte und es im Release weg ist? Ich weiß nicht was er bei QList<T> zu meckern hat :(

so long

jd
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Wenn in QList<> nichts drin ist und Du auf QList<>[0] zugreifst - was wird da wohl passieren?
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
jd
Beiträge: 130
Registriert: 22. Januar 2008 17:55

Beitrag von jd »

Ja das ist klar aber wenn da nichts drinnen ist, wird auch nichts angezeigt, wieso kann ich dann Werte ausgeben?

Code: Alles auswählen

QString test;

	for (int i = 0; i < disk.size(); i++) {
		test.append(disk[i]->filesystem);
		test.append("\t");
		test.append(disk[i]->size);
		test.append("\t");
		test.append(disk[i]->used);
		test.append("\t");
		test.append(disk[i]->avail);
		test.append("\t");
		test.append(disk[i]->usedPercent);
		test.append("\t");
		test.append(disk[i]->mountPoint);
		test.append("\n");
	}

	labelDiskSpace->setText(test);
Das klappt einwandfrei... Ich meine wenn da irgendwo was leer wäre würde er es ja auch nicht anzeigen. Das ist ja das Problem warum ich den Fehler nicht nach voll ziehen kann.[/code]
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Da Du uns nicht zeigst wo der Fehler auftritt, können wir auch nicht sagen was falsch ist.
Am besten mal mit dem Debugger einen Breakpoint in qlist.h an der Stelle machen an der das Assert erzeugt wird und dann den Backtrace anschauen.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

was könnte ich an meinem Code besser machen
z.B. anstelle des structes:

Code: Alles auswählen

typedef struct  {
      ...
} SHardDrive; 
dann noch:

Code: Alles auswählen

#include </usr/include/stdio.h> 
.....?!?

und vor dem Zugriff der QList auf deine Annahmen pruefen:

Code: Alles auswählen

 list = line.split(QRegExp("\\s+"), QString::SkipEmptyParts); 
 Q_ASSERT(list.size() >= 6);
...
 /** Das wird noch in eine Schleife gepackt */
Q_ASSERT(disk.size() >= 1);
 labelDiskSpace->setText(disk[0].filesystem); 
jd
Beiträge: 130
Registriert: 22. Januar 2008 17:55

Beitrag von jd »

Du glaubst gar nicht wie gerne ich dir sagen würde woran das liegt :shock:

Also ich habe habe da jetzt mal einen Breakpoint gesetzt und geschaut, was ich da aus Eclipse auslesen kann.
"(((((p)(((((window)).disk)).))).shared_null)).array"
Target request failed: mi_cmd_var_create: unable to create variable object.
"(((((p)(((this))->))).d)).array"
Target request failed: mi_cmd_var_create: unable to create variable object.
Ich kann damit nicht wirklich was anfangen, ich denke mal das, dass Problem an
QList<SHardDrive*> disk; liegt. Aber ich wüsste jetzt nicht was daran falsch ist.

Der Fehler tritt nicht beim compilieren auf, sonder beim starten der Anwendung. Das nächste was mich sehr stutzig macht ist, das der Fehler nicht immer kommt sonder nur ab und zu.

Ablauf:
Auf Anwendung starten klicken;
>>Fehler
Auf Anwendung starten klicken;
>> geht

Code des Fehlers:

Code: Alles auswählen

{ Q_ASSERT_X(i >= 0 && i < p.size(), "QList<T>::operator[]", "index out of range");
In meinem Debugger sind die einzelnen Schritte nummeriert, und da steht:
4 QList<QString>::operator[]() /usr/include/qt4/QtCore/qlist.h:392 0x0804f94a
Ich weiß nicht was es mit 0x0804f94a auf sich hat, ich habe mal auf dem Stack(?) gesucht, nach der Bezeichnung, jedoch nichts gefunden.

so long
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Die anderen Schritte wären auch noch interessant, nicht nur der 4.
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

ueberleg doch mal...

Code: Alles auswählen

The  popen()  function opens a process by creating a pipe, forking, and
invoking the shell.
Frage 1: was bedeutet "fork" (findest du sicher heraus)
Frage 2: wie lange hat dein Code vom fork zum read (TextStream)
Frage 3: warum sicherst du dich nicht mit Q_ASSERT ab, damit dein Programm nicht innerhalb von Qt-Code abgebrochen wird...
jd
Beiträge: 130
Registriert: 22. Januar 2008 17:55

Beitrag von jd »

OK hier alle Debugger schritte bis zu Terminierung.
1 main() /home/osadmin/workspace/config-control/src/main.cpp:6 0x08050ffb
2 CMainWindow() /home/osadmin/workspace/config-control/src/MainWindow/MainWindow.cpp:14 0x0804ee37
3 CMainWindow::calculateDiskSpace() /home/osadmin/workspace/config-control/src/MainWindow/MainWindow.cpp:49 0x0804e5b5
4 QList<QString>::operator[]() /usr/include/qt4/QtCore/qlist.h:392 0x0804f94a
5 qt_assert_x() global/qglobal.cpp:1925 0xb772eb3c
6 qFatal() global/qglobal.cpp:2392 0xb772eae9
7 qt_message_output() global/qglobal.cpp:2160 0xb772ea35
8 abort() 0xb749d891
9 raise() 0xb749bf15
10 __kernel_vsyscall() 0xb7f7f410
Ich habe jeden Punkt angeklickt und mir die Variablen angeschaut. nur bei Punkt 4 ist ein Fehler:
array <mi_cmd_var_create: unable to create variable object>
Der Eclipse-Debugger ist der ein zigste den ich habe ...

[/quote]
jd
Beiträge: 130
Registriert: 22. Januar 2008 17:55

Beitrag von jd »

Hallo solarix, werde mich umgehend schlau machen.

PS ich habe leider noch nie mir Q_ASSERT gearbeitet, und weiß nicht viel darüber, was ich umgehend ändern werde.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Da steht es eh:

Code: Alles auswählen

3 CMainWindow::calculateDiskSpace() /home/osadmin/workspace/config-control/src/MainWindow/MainWindow.cpp:49 0x0804e5b5 
In dieser Zeile übergibst du einen falschen Index an QList. Also dort Breakpoint setzen und die Variablen überprüfen, oder mit qDebug() die Variablen ausgeben.
ObeliX
Beiträge: 59
Registriert: 14. November 2007 17:47

Beitrag von ObeliX »

Code: Alles auswählen

   while (!in.atEnd()) {
      line = in.readLine();
      QStringList list;
      list = line.split(QRegExp("\\s+"), QString::SkipEmptyParts);

      hdd.filesystem = list[0];
      hdd.size = list[1];
      hdd.used = list[2];
      hdd.avail = list[3];
      hdd.usedPercent = list[4];
      hdd.mountPoint = list[5];

      disk.append(hdd);
   } 
setzt doch mal nach dem split ne ausgabe rein :

Code: Alles auswählen

if(list.size()<6) {
  QMessageBox::warning(this,"Error","Ich bin garnicht lang genug !!!\n");
  continue;
}
ma gucken was passiert 8)

gruß Obel
Antworten