Pergunta

Como faço o check-in C ++ se um arquivo é um arquivo comum (e não é um diretório, um cachimbo, etc.)? Eu preciso de uma função isFile ().

DIR *dp;
struct dirent *dirp;

while ((dirp = readdir(dp)) != NULL) {
if ( isFile(dirp)) {
     cout << "IS A FILE!" << endl;
i++;
}

Eu tentei comparar dirp-> d_type com (char não assinado) 0x8, mas parece não portátil através de sistemas diferentes.

Foi útil?

Solução

Você precisa chamar stat (2) sobre o arquivo, e depois usar a macro S_ISREG em st_mode.

Algo como (adaptado de esta resposta ):

#include <sys/stat.h>

struct stat sb;

if (stat(pathname, &sb) == 0 && S_ISREG(sb.st_mode))
{
    // file exists and it's a regular file
}

Outras dicas

Você pode usar o portátil boost::filesystem (A biblioteca padrão C ++ não poderia ter feito isso até recente introdução de std :: filesystem em C ++ 17):

#include <boost/filesystem/path.hpp>
#include <boost/filesystem/operations.hpp>
#include <iostream>

int main() {
    using namespace boost::filesystem;

    path p("/bin/bash");
    if(is_regular_file(p)) {
        std::cout << "exists and is regular file" << std::endl;
    }
}

C ++ em si não lida com sistemas de arquivos, então não há nenhuma maneira portátil na própria linguagem. exemplos específicos de plataforma são stat para * nix (como já foi observado por Martin v. Löwis) e GetFileAttributes para Windows.

Além disso, se você não é alérgico a impulsionar , há bastante cross-platform boost::filesystem.

Em C ++ 17, você pode usar std :: filesystem :: is_regular_file

#include <filesystem> // additional include

if(std::filesystem::is_regular_file(yourFilePathToCheck)) 
    ; //Do what you need to do

Note que a versão anterior do C ++ pode ter tido-lo sob std :: experimental :: filesystem (Fonte: http://en.cppreference.com/w/cpp/filesystem/is_regular_file )

Obrigado a todos pela ajuda, eu tentei com

while ((dirp = readdir(dp)) != NULL) { 
   if (!S_ISDIR(dirp->d_type)) { 
        ... 
        i++; 
   } 
} 

E ele funciona muito bem. =)

#include <boost/filesystem.hpp>

bool isFile(std::string filepath)
{
    boost::filesystem::path p(filepath);
    if(boost::filesystem::is_regular_file(p)) {
        return true;
    }
    std::cout<<filepath<<" file does not exist and is not a regular file"<<std::endl;
    return false;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top