#c #linux #linux-kernel #stat
#c #linux #linux-ядро #статистика
Вопрос:
Я использую «S_ISDIR» и «S_ISREG», но получаю сообщение об ошибке, что они не объявлены. Я попытался использовать его в macOS (используя S_IFDIR и S_IFREG), и это сработало, но не в терминале Linux.
error: ‘S_ISDIR’ undeclared (first use in this function)
error: ‘S_ISREG’ undeclared (first use in this function); did you mean ‘S_ISDIR’?
struct stat s;
if(stat(fileName, amp;s) == 0 )
{
if( s.st_mode amp; S_ISDIR )
{
return false;
}
else if( s.st_mode amp; S_ISREG )
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
return false;
Комментарии:
1. Ваши сообщения об ошибках относятся к
S_ISDIR
andS_ISREG
, но ваш код используетS_IFDIR
andS_IFREG
. Пожалуйста, покажите нам код, соответствующий сообщениям об ошибках.2. @zwol Я изменил код. Извините за это.
Ответ №1:
Вы неправильно используете макросы. Это функциональные макросы, которые принимают режим в качестве параметра:
if( S_ISDIR(s.st_mode) )
{
return false;
}
else if( S_ISREG(s.st_mode) )
{
return true;
}
else
{
return false;
}
Комментарии:
1. Обратите внимание, что невозможно
S_ISDIR(x)
S_ISREG(x)
одновременно и быть true, поэтому это можно упростить доreturn !!S_ISREG(s.st_mode)
.
Ответ №2:
Возможно, вам интересно, почему ваш исходный код с S_IFREG
и S_IFDIR
работал в одной операционной системе, а не в другой. Это связано с тем, что S_IFxxx
константы являются необязательными в некоторых версиях стандарта POSIX (это стандарт, который определяет содержимое sys/stat.h
).
S_ISxxx
Функциональные макросы должны быть доступны, поэтому лучше использовать их, когда есть возможность, но иногда использование S_IFxxx
констант может сделать код намного понятнее. Они являются макросами, поэтому вы можете проверить их наличие с #ifdef S_IFREG
помощью (если S_IFREG
доступно, можно с уверенностью предположить, что и другие тоже).
Некоторые операционные системы не предоставляют S_IFxxx
константы по умолчанию, но предоставляют, если вы помещаете #define _XOPEN_SOURCE 700
выше всех своих #include
строк. Linux обычно не является одной из этих операционных систем, но она становится одной из этих операционных систем, если вы используете -ansi
или -std=cNN
в командной строке компилятора. (Примечание. по причинам, слишком сложным для понимания здесь, обычно ошибочно использовать эти переключатели вместо -std=gnuNN
.)