Disclaimer: Dieser Thread wurde aus dem alten Forum importiert. Daher werden eventuell nicht alle Formatierungen richtig angezeigt. Der ursprüngliche Thread beginnt im zweiten Post dieses Threads.
Miniklausur 25.10.12
Habe mal versucht, Aufgabe 2 zu implementieren. Allerdings versagt meine Lösung (spätestens) beim Sortieren.
Erkennt da jemand, was ich falsche mache?
#include <dirent.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#define abs(a) ( ( (a) < 0 ) ? (-a) : (a) )
// Tupel-Struktur
struct Entry {
char name[NAME_MAX + 1];
off_t size;
};
int entryCompare(const void* a, const void* b) {
// Hilfsfunktion fuer qsort
struct Entry* first = (struct Entry*) a;
struct Entry* second = (struct Entry*) b;
if (first->size > second->size) {
return 1;
} else if (first->size == second->size) {
return 0;
} else {
return -1;
}
}
int getSortedEntries(struct Entry entries[], unsigned int maxEntries) {
int count = 0;
DIR* dir = NULL;
if (NULL == (dir = opendir("."))) {
return 0;
}
struct dirent* entry;
struct stat buf;
errno = 0;
while (NULL != (entry = readdir(dir))) {
if (count >= maxEntries) {
// Array war zu klein
count = -count; // = -maxEntries
break;
}
char* name = entry->d_name;
if (-1 == lstat(name, &buf)) {
return 0;
}
entries[count].size = buf.st_size;
strcpy(entries[count].name, name);
count++;
errno = 0;
}
// Fehlerueberpruefung von readdir
if (errno != 0) {
return 0;
}
qsort((void*) entries, abs(count), sizeof(struct entry*), entryCompare);
closedir(dir);
return count;
}
Und zum Testen:
int main(int argc, char* argv[]) {
unsigned int maxEntries = 10;
struct Entry entries[10];
int found = getSortedEntries(entries, maxEntries);
for (int i=0; i<maxEntries && i < abs(found); i++) {
printf("%lld\t%s\n", (long long) entries[i].size, entries[i].name);
}
return EXIT_SUCCESS;
}
Wenn ich nicht irre entspricht CurrentWorkingDirectory nicht zwingend “.” ! Wenn die Datei beispielsweise über ein Link aufgerufen wird.
Lstat benötigt auch den kompletten Pfad und nicht nur den Dateinamen.
Weiterhin kann man wenn man lustig ist auch closedir noch auf Fehler abfragen.
[m]getcwd(x, NULL)[/m] ist nicht in POSIX spezifiziert, also nicht erlaubt. Außerdem fehlt danach das [m]free(3)[/m].
Hier musst du noch die [m]errno[/m] auf 0 setzen, da der Wert der [m]errno[/m] nach einem erfolgreichen Bibliotheksfunktionsaufruf nicht definiert ist.
Ich hab mir die Aufgabe nicht durchgelesen, aber ist die Pfadlänge wirklich auf 300 Zeichen limitiert? Sinnvoller wäre es hier, [m]newPath[/m] passend lang zu erzeugen:
Allerdings liegt die Datei ja sowieso im aktuellen Arbeitsverzeichnis, also brauchst du das nicht. Einfach nur der Dateiname reicht hier, da es ja immer relativ zum aktuellen Arbeitsverzeichnis gehandhabt wird.
Doch, das aktuelle Arbeitsverzeichnist ([m]getcwd(3)[/m]) ist immer „.“! Wie die Datei aufgerufen wird ist egal. [m]getcwd(3)[/m] braucht man eigentlich nur, wenn man das Arbeitsverzeichnist ausgeben will, aber nicht wenn man relativ dazu Pfade braucht.
Nein, da die Dateien im aktuellen Verzeichnis sind, reicht der Dateiname.
Nein. Du prüfst nach der Schleife die [m]errno[/m] und da diese auch im Erfolgsfall != 0 sein kann, wird das [m]return 0[/m] ausgeführt, obwohl kein Fehler aufgetreten ist.