Разобрать расширение файла из пути к файлу в C - PullRequest
0 голосов
/ 10 ноября 2009

Ранее я использовал следующий код, чтобы определить, является ли файл файлом .exe или .o, и поэтому для binFile было установлено значение 1:

if(strstr(fpath,".exe") != NULL || strstr(fpath,".o") != NULL)
          binFile = 1;

В процессе отладки я заметил, что этот метод также устанавливает binFile в 1 с файлами, такими как foo.out или foo.execute. Что я действительно хочу, так это сопоставить '.exe \ 0' и '.o \ 0', но strstr () говорит, что игнорирует завершающие байты NUL. Как мне поступить об этом?

Спасибо

Ответы [ 7 ]

6 голосов
/ 11 ноября 2009
#include <stdio.h>
#include <string.h>

int endswith(const char* haystack, const char* needle)
{
    size_t hlen;
    size_t nlen;
    /* find the length of both arguments - 
    if needle is longer than haystack, haystack can't end with needle */
    hlen = strlen(haystack); 
    nlen = strlen(needle);
    if(nlen > hlen) return 0;

    /* see if the end of haystack equals needle */
    return (strcmp(&haystack[hlen-nlen], needle)) == 0;
}

int main(int argc, char** argv) {

    if(argc != 3) {
        printf("Usage: %s <string> <test-ending>\n", argv[0]);
        return 1;
    }

    printf("Does \"%s\" end with \"%s\"? ", argv[1], argv[2]);

    if(endswith(argv[1], argv[2])) {
        printf("Yes!\n");
    } else {
        printf("No!\n");
    }

    return 0;
}
4 голосов
/ 11 ноября 2009
char *ext = strrchr(fpath, '.');

if (ext && (!strcmp(ext, ".exe") || !strcmp(ext, ".o")))
   binfile = 1;

Если ваша система имеет BSD / POSIX strcasecmp, вам, вероятно, следует использовать ее вместо strcmp.

4 голосов
/ 10 ноября 2009
int iLen = strlen(fpath);
if  ((iLen >= 4 && strcmp(&fpath[iLen - 4], ".exe") == 0)
  || (iLen >= 2 && strcmp(&fpath[iLen - 2], ".o") == 0))
   binfile = 1;

Редактировать добавлен тест на длину для обработки очень коротких имен файлов.

2 голосов
/ 11 ноября 2009

Мне нравится получать расширение, а затем проверять его.

char *suffix = strrchr(fpath,'.');

if (suffix)
{
  suffix++;
  if (!strcasecmp(suffix,"exe"))
  {
    // you got it
  }
}

Инкремент суффикса в порядке, поскольку вы знаете, что он указывает на найденный период в этой точке. Увеличение его в худшем случае заставит его указывать на нулевой символ завершения, который вообще не будет беспокоить strcasecmp.

Таким же образом вы можете легко проверить список расширений.

2 голосов
/ 10 ноября 2009

Вы можете проверить один результат результата strstr (принимая во внимание длину строки поиска), чтобы убедиться, что он равен NULL. Пример:

const char* p = strstr(fpath,".exe");

if (p != NULL && *(p + 4 + 1) == 0) // 4 is the length of ".exe"; +1 should get you to \0
    binFile = 1;
0 голосов
/ 07 мая 2011

Вы также можете использовать _splitpath / _wsplitpath, который является частью CRT.

http://msdn.microsoft.com/en-us/library/e737s6tf(v=vs.80).aspx

0 голосов
/ 11 ноября 2009

один способ сделать это:

char * suffix = fpath;
char * i = fpath;
while (*i++) {
    if (*i == '.') {
        suffix = i;
    }
}

if (!strcmp(suffix, ".o") || !strcmp(suffix, ".exe")) {
    /* do stuff */
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...