d_type je optimalizace rychlosti pro úsporu lstat(2) volání, pokud je to podporováno.
Jako readdir (3) manuálová stránka zdůrazňuje, že ne všechny souborové systémy vracejí skutečné informace v d_type pole (obvykle proto, že čtení inodu by vyžadovalo další hledání disku, jako je tomu v případě XFS, pokud jste nepoužili mkfs.xfs -n ftype=1 (předpokládá se -m crc=1 což ještě není výchozí nastavení). Souborové systémy, které vždy nastavují DT_UNKNOWN jsou v reálném životě běžné a nelze je ignorovat. XFS není jediným příkladem.
Vždy potřebujete kód, který se vrátí k použití lstat (2) pokud d_type==DT_UNKNOWN , pokud samotný název souboru nestačí k rozhodnutí, že je nezajímavý. (To je případ některých volajících, například find -name nebo rozšiřující globusy jako *.c , proto readdir nezahrnuje režii jeho vyplňování, pokud by to vyžadovalo další čtení disku.)
Linux getdents(2) manuálová stránka obsahuje ukázkový program, který dělá to, o co se pokoušíte, včetně bloku řetězeného ternárního operátora pro dekódování d_type pole do textových řetězců. (Jak zdůrazňují ostatní odpovědi, vaše chyba je vytisknout jej jako znak, spíše než jej porovnat s DT_REG , DT_DIR , atd.)
Každopádně ostatní odpovědi většinou pokrývaly věci, ale postrádaly kritický detail, že POTŘEBUJETE záložní řešení pro případ, kdy d_type == DT_UNKNOWN (0 v systému Linux. d_type je až do Linuxu 2.6.4 uloženo v tom, co bývalo výplňovým bytem).
Aby byl váš kód přenosný, musí zaškrtnout struct dirent dokonce MÁ d_type pole, pokud jej použijete, jinak se váš kód nebude ani zkompilovat mimo systémy GNU a BSD. (viz readdir(3) )
Napsal jsem příklad hledání adresářů pomocí readdir pomocí d_type s přechodem na stat když d_type není k dispozici v době kompilace, když je DT_UNKNOWN a pro symbolické odkazy.
d_type ve struktuře return udává číslo pro typ. Nemůžete to vytisknout přímo, protože použité hodnoty nelze vytisknout, když jsou interpretovány jako ASCII (například jsou 4 pro adresáře a 8 pro soubory).
Můžete je vytisknout jako čísla takto:
printf("%d ", dent->d_type)
Nebo je porovnejte s konstantami jako DT_DIR a vytvořit z toho nějaký smysluplný výstup, jako je typ znaku:
if(dent->type == DT_DIR) type = 'd'
Vytiskněte d_type jako celé číslo takto:
printf("%d ", dent->d_type);
a uvidíte smysluplné hodnoty.