Return eines zweidimensionalen integer Arrays
-
Hallo,
ich habe zwei Probleme:
1. Letzte Zeile bei "return rtrn;":
error: invalid conversion from ‘int (*)[2]’ to ‘int’
2. Cout funktioniert nicht und gibt nichts aus, egal an welcher Stelle, äusserst merkwürdig. Scheinen doch einige ganzschön große Fehler drin zu sein.Compiler gcc, Ubuntu 10.10
Hier der Code:
scan.h#ifndef _SCAN_H_ #define _SCAN_H_ #include <iostream> #include <dirent.h> #include <string.h> #include <stdlib.h> class Scan { public: int doScan(); int rtrn[100][2], pos_rtrn; private: int getLine(std::string regEx, char* file, char* dir); }; #endif // _SCAN_H_#include "scan.h" int Scan::getLine(std::string regEx, char* file, char* dir) { std::string strCmd = "sed -e " + regEx + " "; char* cmd = strdup(strCmd.c_str()); strcat(cmd, dir); strcat(cmd, file); return system(cmd); } int Scan::doScan() { DIR *hdir; struct dirent *entry; char* directory = getenv("HOME"); strcat(directory, "/.config/autostart/"); char type[] = ".desktop"; hdir = opendir(directory); pos_rtrn = 0; do { entry = readdir(hdir); if (entry) { if (strstr(entry->d_name, type) != NULL) { rtrn[pos_rtrn][0] = getLine("'/^Name=/!d'", entry->d_name, directory); rtrn[pos_rtrn][1] = getLine("'/^Exec=/!d'", entry->d_name, directory); pos_rtrn++; } } } while (entry); closedir(hdir); rtrn[99][1] = pos_rtrn; return rtrn; }Was das ganze machen soll:
Bestimmte Zeilen aus .desktop-Autostart-Einträgen aus dem Verzeichnis ~/.config/autostart per sed als return-Wert in dem Array rtrn zurückgeben.Wäre nett, wenn das mal jemand durchschauen könnte. Danke schonmal.

P.S. für die komische Einrückung kann ich nichts

-
Arrays können nicht als returnwert einer Funktion zurück gegeben werden.
-
Kapsel das Array in eine Klasse und du hast Wertsemantik.
Übrigens darfst du
char* directory = getenv("HOME"); strcat(directory, "/.config/autostart/");nicht machen. Der von
std::getenv()zurückgegebene Speicher gehört nicht dir.
-
Arrays können nicht als returnwert einer Funktion zurück gegeben werden.
Ok dann ists kein Wunder dass das so nicht funktioniert.
Nexus schrieb:
Kapsel das Array in eine Klasse und du hast Wertsemantik.
Da bin ich jetzt überfragt, wie meinst du das genau?
Übrigens darfst du
char* directory = getenv("HOME"); strcat(directory, "/.config/autostart/");nicht machen. Der von
std::getenv()zurückgegebene Speicher gehört nicht dir.Ok jetzt wo du es sagst fällt es mir auch auf.

-
de4dtronic schrieb:
Nexus schrieb:
Kapsel das Array in eine Klasse und du hast Wertsemantik.
Da bin ich jetzt überfragt, wie meinst du das genau?
Er meint so etwas wie
struct my_array{ int data[5]; }Oder du nimmst halt gleich std::vector wie es sich gehört oder boost::array, wenn es unbedingt statisch sein muss.
Wie kann es übrigens sein, dass du davon nichts gehört hast, von Arrays aber schon? Du liest nicht zufällig Bücher von Jürgen Wolf?
-
SeppJ schrieb:
Er meint so etwas wie
struct my_array{ int data[5]; }Oder du nimmst halt gleich std::vector wie es sich gehört oder boost::array, wenn es unbedingt statisch sein muss.
Habe mir mal std::vector angeschaut und das scheint wirklich besser zu sein. Allerdings kann ich diese arrays doch genauso wenig in einem return angeben, oder etwa doch?
Wie kann es übrigens sein, dass du davon nichts gehört hast, von Arrays aber schon? Du liest nicht zufällig Bücher von Jürgen Wolf?
Nein, aber das hat wohl vorallem damit zu tun, dass ich von anderen Sprachen komme und mir bei denen soetwas noch nicht begegnet ist. Und bin auch nicht an C++ rangegangen, indem ich ein Buch von vorne bis hinten gelesen habe, sondern indem ich einfach mal drauf losgeschrieben habe. Deshalb fehlen mir wohl ein paar c++-spezifische Kentnisse.
-
Man kann einen vector zurückgeben. Er ist auch nur ein Objekt wie jede andere Klasse auch.
-
HighLigerBiMBam schrieb:
Man kann einen vector zurückgeben. Er ist auch nur ein Objekt wie jede andere Klasse auch.
Ok dann werde ich mir das ganze mal anschauen. Danke an alle

-
Ich bekomme das mit vector nicht ganz hin.
Mein Multidimensionaler würde so aussehen:std::vector< std::vector<int> > rtrn(100, std::vector<int>(2));An einer Stelle wird das so vorgeschlagen, an einer anderen steht, dass das so nicht geht. Bringt auch Fehler:
error: expected identifier before numeric constant
error: expected ‘,’ or ‘...’ before numeric constantMan nehme testweise ein Beispiel von hier:
std::vector<int> array(10);error: expected identifier before numeric constant
error: expected ‘,’ or ‘...’ before numeric constantLiegt das an mir oder gar an gcc?
-
de4dtronic schrieb:
Liegt das an mir oder gar an gcc?
Leitfaden: Es liegt nie am Compiler. Compiler werden täglich Abermillionen (Milliarden?) Mal benutzt und haben daher extrem wenige Fehler.
Hast du auch den Header vector eingebunden?
-
SeppJ schrieb:
]Leitfaden: Es liegt nie am Compiler. Compiler werden täglich Abermillionen (Milliarden?) Mal benutzt und haben daher extrem wenige Fehler.
Ich meinte auch nicht, dass er Fehler hat, sondern dass er möglicherweise einen anderen Syntax erwartet. Das war einfach die einzige Erklärung, die mir dazu eingefallen ist, natürlich funktioniert standardmäßiger C++-Code mit jedem Compiler gleichermassen..
SeppJ schrieb:
Hast du auch den Header vector eingebunden?
Ja
-
Dann zeig bitte ein minimales Beispiel, welches den Fehler zeigt. Ergänzt man deine bisherigen Codeschnipsel nämlich minimal zu
#include <vector> std::vector<int> array(10); std::vector< std::vector<int> > rtrn(100, std::vector<int>(2));dann compiliert das tadellos. Der Fehler muss also woanders liegen.
-
Ok, beim Erstellen eines demonstrierenden Beispiels ist mir aufgefallen, dass wenn das ganze außerhalb der Klassendefinition steht, einwandfrei funktioniert. Danke.

-
de4dtronic schrieb:
Ok, beim Erstellen eines demonstrierenden Beispiels ist mir aufgefallen, dass wenn das ganze außerhalb der Klassendefinition steht, einwandfrei funktioniert. Danke.

Wie bei jeder anderen Klasse auch. Du kannst schließlich in der Klassendefinition keinen Konstruktor angeben, dieser gehört in die Initialisierungsliste. Einzige Ausnahme sind static Elemente von einfachen Datentypen, wobei ich jetzt so auswendig weiß, ob das Standard oder Compilerfeature ist.
-
class foo { public: inline int const (*func() const)[2] { return values; } private: int values[100][2]; };Natürlich ist das mit einem Typedef deutlich übersichtlicher:
class foo { public: typedef int const (*foo_t)[2]; inline foo_t func() const { return values; } private: int values[100][2]; };
-
So jetzt bin ich immerhin so weit, dass das ganze kompiliert. Allerdings mehr auch nicht: Segmentation fault.
Ich wette, ich habe wieder einige wirklich dumme Fehler drinne, wäre nett wenn nochmal jemand kurz drübergeht.
Ich packe das jetzt einfach mal übersichtlich der Reihe nach in ein Code-Tag. Mir ist klar, dass einiges noch sehr unelegant gelöst ist, aber es geht erstmal darum dass das funktioniert.

Also hier der Code, nicht kompilierbar, dafür übersichtlich:
std::vector< std::vector<int> > Scan::doScan() { std::vector< std::vector<int> > rtrn(100, std::vector<int>(2)); do { entry = readdir(hdir); if (entry) { if (strstr(entry->d_name, type) != NULL) { rtrn[pos_rtrn][0] = getLine("'/^Name=/!d'", entry->d_name, directory); rtrn[pos_rtrn][1] = getLine("'/^Exec=/!d'", entry->d_name, directory); pos_rtrn++; } } } while (entry); closedir(hdir); rtrn[99][1] = pos_rtrn; return rtrn; } // ---------------------------------- std::vector< std::vector<int> > entrys = scanAutostarts.doScan(); int entrys_num = entrys[99][1]; int i = 0; for(int i; i < entrys_num; i++) { rl->pushBack(refListStore, liststore, true, toStr(entrys[i][1]), toStr(entrys[i][2])); }Danke schonmal, ihr seid super

-
int i = 0; for(int i; i < entrys_num; i++)Doppelt ist schlecht. Lieber einmal richtig, und zwar innerhalb
for.Ach ja, und Arraygrössen solltest du auch noch beachten.
-
Nexus schrieb:
int i = 0; for(int i; i < entrys_num; i++)Doppelt ist schlecht. Lieber einmal richtig, und zwar innerhalb
for.Ach ja, und Arraygrössen solltest du auch noch beachten.
Hmm, ich sage ja dumme Fehler.

In diesem Fall gibt es den Array nur mit [>99][0|1], stimmt das soweit? Den pushBack-Aufruf habe ich abgeändert, denke mal das war das einzige.Funktioniert leider immer noch nicht, weiter Ideen?

-
Code zeigen. Ich bin mir nicht sicher, ob du die Fehler richtig korrigiert hast.
-
SeppJ schrieb:
Code zeigen. Ich bin mir nicht sicher, ob du die Fehler richtig korrigiert hast.
for(int i = 0; i < entrys_num; i++) // und rl->pushBack(refListStore, liststore, true, entrys[i][0], entrys[i][1]);
-
std::string Scan::toStr(int var) { std::ostringstream tmp; tmp << var; return tmp.str(); }Du mußt die toStr in den Namensraum deiner Klasse injizieren.
Ansonsten hättest Du nur eine globale toStr.edit:
Sorry, hab [edit] statt [quote] geklickt und Deine Frage kaputtgemacht.