Неправильное использование неполного типа '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.
Не стоит забывать включать некоторые заголовки или определения, теперь я столкнулся с этой проблемой, но не с ошибкой, о которой предупреждал.
мой 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
?