Intereting Posts
Ошибка проверки выполнения во время выполнения # 2 – Урон вокруг переменных «индексов» был поврежден Параметры printf, влияющие друг на друга C: Как сравнить две строки? почему мы не можем напечатать значение в двоичной форме, как десятичная, восьмеричная, шестнадцатеричная форма? Является ли логическое отрицание нулевого (! 0) компилятора, зависящего от C? пересылка пакетов для обслуживания на одном и том же хосте без использования петлевой сети программа для изменения строки идентификатор дочернего и родительского процессов Как эффективно структурировать программу C X11 Подождите и получите текст буфера обмена Почему это определение структуры добавляет лишний байт использования памяти? В C, как ограничить область глобальной переменной файлом, в котором она объявлена? В C вы можете иметь 128-битное битовое поле Ссылка Visual C повторяет статическую библиотеку MinGW Преобразование целого числа в строку в C без sprintf

Проверьте, является ли файл конкретным типом в C

Я пишу свою первую программу на C, хотя я исхожу из фона C ++.

Мне нужно выполнить итерацию через каталог файлов и проверить, является ли файл заголовком, а затем возвращать счетчик.

Мой код выглядит следующим образом: это довольно рудиментарно, я думаю:

static int CountHeaders( const char* dirname ) { int header_count = 0; DIR* dir_ptr; struct dirent* entry; dir_ptr = opendir( dirname ); while( ( entry = readdir( dir_ptr ) ) ) { if ( entry->d_type == DT_REG ) { //second if statement to verify the file is a header file should be??? ++header_count; } } closedir( dir_ptr ); return header_count; } 

Что было бы хорошим оператором if, чтобы проверить, является ли файл заголовком?

Просто проверьте, является ли расширение файла .h , например:

 const char *ext = strrchr (entry->d_name, '.'); if ((ext != NULL) && (!strcmp (ext+1, "h"))) { // header file } 

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

Каждая структура dirent имеет имя d_name содержащее имя файла, поэтому я бы посмотрел, следует ли это после некоторого шаблона, например, заканчивается на .h или .hpp .

Это будет код в соответствии с:

 int len = strlen (entry->d_name); if ((len >= 2) && strcmp (&(entry->d_name[len - 2]), ".h") == 0)) header_count++; if ((len >= 4) && strcmp (&(entry->d_name[len - 4]), ".hpp") == 0)) header_count++; 

Конечно, это не поймает поистине злых людей от вызова своих исполняемых файлов ha_ha_fooled_you.hpp но, хотя они не в меньшинстве.

Вы даже можете рассмотреть функцию endsWith() чтобы сделать вашу жизнь проще:

 int endsWith (char *str, char *end) { size_t slen = strlen (str); size_t elen = strlen (end); if (slen < elen) return 0; return (strcmp (&(str[slen-elen]), end) == 0); } : if (endsWith (entry->d_name, ".h")) header_count++; if (endsWith (entry->d_name, ".hpp")) header_count++; 

Есть несколько более эффективных методов, чем проверка расширения файла.

В Википедии есть хорошая статья здесь и здесь . Последняя идея называется магической базой чисел, которая по существу означает, что если файл содержит последовательность blah, то это тип соответствия, указанный в базе данных. Иногда число имеет ограничения на места, и иногда это не так. Этот метод IMO более точен, хотя и медленнее, чем обнаружение расширения файла.

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

Вы можете проверить, являются ли последние несколько символов одним из расширений header-file, .h, .hpp и т. Д. Используйте имя dirent d_name для имени файла.

Или вы можете запустить команду «файл» и проанализировать ее результат.

Вероятно, вы просто хотите проверить расширение файла. Используя dirent , вы хотели бы посмотреть на d_name .

Это зависит от вас.

Самый простой способ – просто посмотреть имя файла (d_name) и проверить, заканчивается ли оно чем-то вроде «.h» или «.hpp» или что-то еще.

С другой стороны, открытие файла и фактическое его чтение, чтобы проверить, действительно ли он c / c ++, будет более сложным … вы можете запустить его через компилятор, но не каждый заголовок работает сам по себе, так что тест даст вам много ложных негативов.