Неправильное использование неполного типа 'DIR'

Я пытаюсь скомпилировать этот код, который отлично работает на Windows, на Linux (Code::Blocks):

/* Edit: Includes */
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <...>
/**/

/* === */

/* Function code */
DIR *dp;
dirent *ep;
string name_parent;

dp = opendir(somepath);
name_parent = dp->dd_name; //error
/**/

Так как имена путей в Windows не чувствительны к регистру, я могу прочитать пользовательский ввод, такой как "c://program files" и получить "правильный" путь "C:\Program Files*" (за исключением звездочки - или "F://" -> "F:*"). Я также использую эту переменную для получения списка каталогов с абсолютными значениями пути, так как ep->d_name (после некоторого readdir(), конечно) возвращает путь относительно somepath.

В Linux я получаю ошибку компилятора (для "dp->dd_name"):

ошибка: недопустимое использование неполного типа 'DIR'

Я что-то забыл? Или есть логическая ошибка?

Изменить: я добавил включенные (которые я уже использую) выше.

5 ответов

/* Edit: Includes */
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <...>
/**/

/* === */

/* Function code */
DIR *dp;
dirent *ep;
string name_parent;

dp = opendir(somepath);
ep = readdir(dp);
name_parent = ep->d_name;

/**/

Переменная d_name существует в struct dirent, которая дает имя каталога

Вы не объявили тип DIR! В системах Posix вы бы сказали:

#include <sys/types.h>
#include <dirent.h>

Однако в Windows у вас нет этих возможностей. Вместо этого вы можете использовать функции файловой системы Windows API.

Внутренняя структура DIR не указан, поэтому вы никогда не должны полагаться на него и ожидать, что ваш код будет переносимым.

Источник в glib для Windows говорит об этом DIR:

/*
 * This is an internal data structure. Good programmers will not use it
 * except as an argument to one of the functions below.

Да. Вы пропустили, включая заголовочные файлы.

dirent.h

Не стоит забывать включать некоторые заголовки или определения, теперь я столкнулся с этой проблемой, но не с ошибкой, о которой предупреждал.

мой files.h;

class Files
{
public:
    explicit Files(const char *p_path = 0);
    ~Files();

    /* ....  */
private:
    std::string path;
}

мой files.cpp;

#include <iostream>

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <sys/types.h> // I added this line with @Kerrek SB's advice but nothing changed
#include <dirent.h>
#include <files.h>

static DIR *p_dir = NULL;
static struct dirent *p_ent = NULL;
Files::Files(const char *p_path)
{
    if (p_path == NULL)
    {
        std::cerr << "PATH is NULL" << std::endl;
        exit(EXIT_FAILURE);
    }
    path = p_path;
    p_dir = opendir(p_path);
    if (p_dir == NULL)
    {
        std::cerr << "Cannot open " << path << std::endl;
        exit(EXIT_FAILURE);
    }
}

Files::~Files()
{
    if (p_dir)
    {
        /* Here is my warning occuring in this line and the definition
           line p_dir 'static DIR *p_dir = NULL' */
        delete p_dir; // After changing this line with 'free(p_dir);' warnings gone.
        p_dir = NULL;
    }
}

Предупреждение в строке определения (static DIR *p_dir = NULL;) является 'p_dir' has incomplete type и предупреждение в строке удаления (delete p_dir;) является possible problem detected in invocation of delete operator: [-Wdelete-incomplete],

После изменения delete p_dir; с free(p_dir); оба предупреждения исчезли. Я не знаю точную причину, но это звучит как DIR * Тип действует как void *, Я просто догадываюсь.

Надеюсь это поможет.

Видимо, тип DIR не определено в том месте, где вы пытаетесь его использовать. Может быть, вы забыли #include?

Другие вопросы по тегам