2016-06-22 8 views
0

Ich muss 2 Funktionen schreiben, Filter - Namen> 5 Zeichen und ich muss sie nach Typen sortieren.Scandir Eigene Filterfunktion

Die Filterfunktion sollte so aussehen?

int (* filter) (const struct dirent* entry) { 

    if ((strlen(entry>d_name) - 1) > 5) { 
     return entry; 
    } 
} 

Wie wäre es Art, in dirent seine dirent-> d_type, aber wie zu sortieren?

+1

nur 'int filter (const struct dirent * entry)' ... Sie übergeben einen Funktionszeiger an 'scandir()', aber die Filterfunktion selbst wird nicht als Zeiger deklariert. – Dmitri

+0

'return entry' ist nicht korrekt. Der Rückgabetyp ist "int", also nehme ich an, dass Sie 0 oder 1 zurückgeben sollen. – user3386109

Antwort

1

Haben Sie darüber nachgedacht, einen Blick auf die Seite man 3 scandir zu werfen?

(ich finde das Linux man-pages project Manpages meist up-to-date für C-Bibliothek und Systemebene Programmierung.)

Wenn wir eine Funktion, die die Anrufer angeben, eine Hilfsfunktion unserer Funktion tun soll, rufen Sie muss einige Aufgabe, wir erklären es als Funktionszeiger. Mit anderen Worten, während der Prototyp für die scandir() Funktion ist

int scandir(const char *dirp, struct dirent ***namelist, 
      int (*filter)(const struct dirent *), 
      int (*compar)(const struct dirent **, const struct dirent **)); 

die Prototypen für die Filter- und Vergleichsfunktionen sind eigentlich

int myfilter(const struct dirent *); 
int mycompar(const struct dirent **, const struct dirent **); 

Dumme Implementierungen für die Funktionen (die nicht erfüllen Ihre Trainingsanforderungen) könnte zum Beispiel

int myfilter(const struct dirent *entry) 
{ 
    /* man 3 scandir says "entries for which filter() 
    * returns nonzero are stored". 
    * 
    * Since file names in Linux are multibyte strings, 
    * we use mbstowcs() to find out the length 
    * of the filename in characters. 
    * 
    * Note: strlen() tells the filename length in bytes, 
    *  not characters! 
    */ 
    const size_t len = mbstowcs(NULL, entry->d_name, 0); 

    /* Keep filenames that are 3 or 7 characters long. */ 
    return (len == 3) || (len == 7); 
} 

int mycompar(const struct dirent **entry1, const struct dirent **entry2) 
{ 
    const size_t len1 = mbstowcs(NULL, (*entry1)->d_name, 0); 
    const size_t len2 = mbstowcs(NULL, (*entry2)->d_name, 0); 

    /* Compare by file name lengths (in characters), 
    * sorting shortest file names first. */ 
    return (int)((ssize_t)len1 - (ssize_t)len2); 
} 

Wenn das Schreiben von Code POSIX.1-2008 verwenden, denken Sie daran hinzuzufügen

#define _POSIX_C_SOURCE 200809L 

vor einem #include s. Um Ihren Code korrekt arbeitet in verschiedenen Umgebungen (zB Zeichen statt Bytes in Dateinamen zu zählen, in jedem Linux-System rund um unsere Welt) zu machen, auch #include <locale.h>, und fügen Sie

setlocale(LC_ALL, ""); 

in Ihrem main() bevor Sie etwas lesen/scannen oder schreiben/drucken. (Obwohl es viel mehr kann tun, um ihre Programme noch weiter zu lokalisieren, die oben genannten sehr oft reicht. Verarbeitung von Textdateien sollte mit breiten Zeichenfolgen (L"This is a ωide §tring liteℛal ") und die wchar_t und wint_t Typen für Zeichenfolgen und Zeichen, mit der breiten erfolgen String-I/O-Funktionen Es ist nicht komplexer oder schwer, richtig zu tun, als es in den idiotischen "Die siebenundzwanzig ASCII-Buchstaben sind für jeden ausreichend, auch wenn es Ihren Namen in ein schmutziges Wort in Ihrem macht Muttersprache " Weg.

Wenn Ihr Lehrer diese nicht erwähnt, sollten Sie fragen, warum. Ein Programm, das nicht mit Dateien oder Text Nöminäl Änimäl needs more €, and cowbell umgehen kann, sollte in der heutigen Zeit nicht akzeptabel sein s keine Notwendigkeit, zuerst lernen einen falschen Weg Dinge zu tun, bevor Sie den richtigen Weg zu lernen, weil der richtige Weg ist genauso einfach wie der falsche Weg ist.