Anmelden

Archiv verlassen und diese Seite im Standarddesign anzeigen : Datei auslesen (fgets mit Speicherzugriffsfehler)



Primusio
02-12-2005, 23:01
Hallöchen Community,
ich befasse mich jetzt ein wenig mit C/C++ unter Linux und wollte mir einmal die Festplatten die am System hängen anzeigen lassen. Auch die die nicht gemountet sind, dazu hab ich folgenden Code verfasst.



#include <iostream>

using namespace std;
int main(void) {
string folder[4] = {"hda","hdb","hdc","hdd"};
char tmp[10];

int i;
for(i=0;i<sizeof(folder)/sizeof(string);i=i+1)
{
string filename = "/proc/ide/"+folder[i]+"/media";
FILE *file = fopen(filename.c_str(),"r");
while (fgets(tmp,sizeof(tmp),file)) {
char *p;
if(p = strchr(tmp,'\n'))
*p = 0;
cout << tmp << endl;
};
fclose(file);
};
}


Das kompilieren mit "g++ test2.c -o test2" unter Knoppix 4.02 verläuft ohne Warnungen und Fehler. Wenn ich das Programm ausführe gibt er mir alles aus was ich wissen will aber zum Schluss noch ein "Speicherzugriffsfehler" durch auskomentieren fand ich herraus, dass es an der Zeile mit fgets liegt und daher eigentlich nur mit der tmp Variable zu tun haben kann. Leider habe ich keine Idee für eine Lösung.

Ziel ist es die Datei /proc/ide/hda/media auszulesen steht dort "disk" drin handelt es sich um eine Festplatte.

Ich hoffe jemand kann mir helfen aber ich bitte um Rücksicht bin NOCH kein C Crack :cool:

BLUESCREEN3D
03-12-2005, 01:26
Nach fopen() solltest du überprüfen, ob das Öffnen der Datei überhaupt geklappt hat.

Primusio
03-12-2005, 01:37
Manchmal sieht man den Wald vor lauter Bäumen nicht.
Ich danke dir, ist ja klar schließlich ist nicht immer jeder IDE Controller voll belegt. und fehlt ein Device gibt es auch weder den Ordner noch die Datei um öffnen, ergo Speicherzugriffsfehler.

Danke dir

MfG
Primusio

locus vivendi
03-12-2005, 10:45
Ich hoffe jemand kann mir helfen aber ich bitte um Rücksicht bin NOCH kein C Crack
Dein Snippet ist aber C++, nicht C.
Ich habe noch eine Anmerkung zum Stil, und zwar würde ich statt "int main(void)" lieber "int main()" schreiben. Das void um eine leere Parameterliste zu definieren ist überflüssig, und wird von vielen C++ Programmierern auch nicht gerne gesehen und statt "int i; for(i=0;i<sizeof(folder)/sizeof(string);i=i+1)" lieber "for(int i = 0; i != sizeof(folder)/sizeof(string);++i)" schreiben. So bleibt die Sichtbarkeit des Schleifenzählers auf die Schleife beschränkt. Und "i=i+1", schreibt, glaube ich, kaum jemand.

Gsus
03-12-2005, 12:15
Hallo

ich will das ja jetzt nicht zu einer Grundsatz diskussion fürhen lassen, aber ich wollt doch wenigstens sagen, dass du wenn du nicht objektorientiert programmieren willst (zumindest scheinst du in den Code schnippsel das nicht zu wollen ) würde ich daraus reines C machen und dann #inlclude <stdio.h> anstatt <iostream> dann kannst du das mit der for schleife und der main so lassen und dann noch printf statt cout und dann hast du sauberen C Code.

Okay ist nicht wirklich wichtig aber weil mein Vorredner meinte wie du es in C++ machen solltest wollte ich dir nur sagen wie du es in C machen solltest ;-)

Viel spass beim Programmieren :-D

mfg

Gsus

locus vivendi
03-12-2005, 16:55
[...] würde ich daraus reines C machen und dann #inlclude <stdio.h> anstatt <iostream> dann kannst du das mit der for schleife und der main so lassen [...]
Also natürlich kann er das auch in C++ so lassen. Es ist bloß nicht schön. Allerdings ist (bzw. wäre) das seit C99 noch nicht einmal schöner C-Code.

Joghurt
03-12-2005, 16:58
Und
typ funktionsname(void) ist in C++ auch unnötig, da in C++ ein
int foo()explizit sagt, dass foo keine Parameter nimmt. In C ist das anders, deswegen hat man dafür früher void genutzt.

Primusio
04-12-2005, 05:27
Ich glaube das Forum hier ist bisher das beste was ich bisher besucht habe.
Kein "Lern du erstmal C" oder sonstige dekonstruktive Kritik, im Gegenteil.

Alles sehr hilfreich und auch lehrreich, danke euch Leute.
Ich will versuchen mein Programm in C++ zu schreiben und wie heißt es so schön "learning by doing", denn mal ehrlich, nur wenige von euch werden doch mit einem "Hello World" Programm angefangen haben und dannstep for step weiter gemacht haben.

Man setzt sich doch viel mehr ein Ziel was man machen will und dann schaut man wie man das am besten hinbekommt.

Also hier mein neuer Code aber nicht lachen :)



#include <iostream>
#include <vector>

using namespace std;
int main(int argc, char *argv[]) {
vector<string> tmp1;
tmp1.push_back("hda");
tmp1.push_back("hdb");
tmp1.push_back("hdc");
tmp1.push_back("hdd");
char line[256];
int i;
vector<string> devices;

for(i = 0; i < tmp1.size(); ++i)
{
string filename = "/proc/ide/"+tmp1[i]+"/media";
FILE *file;
if(file = fopen(filename.c_str(),"r"))
{
while(fgets(line,sizeof(line),file))
{
char *p
if(p = strchr(line,'\n'))
*p = 0;
if(0 == strcmp(line, "disk"))
devices.push_back(tmp1[i]);
};
fclose(file);
}
};
return 0;
}


Wie ihr seht hab ich mich für Vectoren entschieden, da der Umgang weitaus einfacher ist. Kritik nehme ich selbstverständlich wieder gern entgegen, solange ich sie auch verstehe :D

Meine nächste Aufgabe wird sein daraus eine Funktion zu machen, die "devices" als Rückgabewert hat. Und das anschließend als header im Hauptprogramm einzubauen, wobei das ja eigentlich kein Problem sein sollte oder ? Einfach mit Endung .h abspeichern und includen. (hoffe ich).

Also Verbesserungsvorschläge sind erwünscht, Lob aber auch ;)
Und falls jemand eine bessere Möglichkeit kennt zu kontrollieren was für Festplatten am System angeschlossen sind nur her damit, allerdings denke ich, dass für mein Wissensstand das /proc Verzeichnis völlig ausreicht.

MfG
Primusio

Joghurt
04-12-2005, 14:59
Erstens gibt es u.U. noch mehr als hdd, z.B. hde. Und zweitens hast du noch SCSI Platten vergessen.
Die Schleife von "hda" bis "hdz" kannst du auch anders lösen:

for (char ch = 'a' ; ch <= 'z' ; ch++) {
string filename = string("/proc/ide/hd") + ch + string("/media");
...
}

Primusio
05-12-2005, 00:49
Danke dir damit geht es natürlich noch besser, da ich mir einen Vector spare und gleich alle Möglichkeiten durchlaufen lassen kann.

SCSI habe ich nicht vergessen, sondern bewusst weggelassen, da sich bei SCSI nicht so leicht auslesen lässt ob es sich dabei um Festplatten handelt. Zumindest wie ich das gesehen habe.

Aber danke für eure Hilfe mal sehen wann ich wieder nicht allein weiter kommen ;)

MfG
Primusio

Primusio
05-12-2005, 02:10
Da hab ich leider schon das nächste Problem für das ich weder hier über die Suche noch bei google und co eine Lösung finde.

Den Vector "devices" hab ich in einem Programm global deklariert, um Ihn in verschiedenen Funktionen nutzen zu können.
Aus meinem Programm pben habe ich eine Funktion gemacht

void getHDDs()
diese rufe ich im Hauptteil auf, damit füllt er mir meinen Vector mit meinen Festplatten, hda und hdb.

Im weiteren Programm nutze ich ncurses und will mit

mvwprintw(local_win, y, x, "%s", devices[i]);
innerhalb einer Schleife mir meine Festplatten ausgeben lassen, allerdings erhalte ich folgenden Fehler


ncurses.c: In function 'void print_menu(WINDOW*, ind)':
ncurses.c:124: Warnung: cannot pass object of non-POD type 'struct
std::basic_string<char, std::char_traits<char>, std::allocator<char> >'
through '...'; call will abort at runtime


Ich habe gelsen, dass der Befehl bei ncurses C statt C++ ist und die Strings in C und C++ nicht identisch sind und habe folgendes probiert.

mvwprintw(local_win, y, x, "%s", devices[i].c_str);

Aber bei dem Versuch erhielt ich folgende Fehlermeldung


ncurses.c: In function 'void print_menu(WINDOW*, int)':
ncurses.c:123: error: invalid use of member (did you forget the '&' ?)


Kann mir jemand vielleicht auch bei dem Problem weiterhelfen ?

Würde euch gern den Code geben aber arbeite mit VMware und da kann ich meines Wissens nach nichts herrauskopieren.

MfG
Primusio

Joghurt
05-12-2005, 14:39
c_str ist eine Methode, also
devices[i].c_str()

Gsus
05-12-2005, 16:32
Ich wollte dich einfach nur loben :D

mfg

gsus

Joghurt
05-12-2005, 17:15
*geschmeichelt verneig*

Primusio
05-12-2005, 17:45
Jungs und natürlich auch Mädchen, Ihr seit die besten danke.
hochachtungsvoll verneig :D