Функция, чтобы проверить, если путь к папке действителен


Это функция, которая проверяет строку на правильный путь Windows в каталог. Она возвращает отрицательное число, если он не 0, если это верно и 1, если он существует:

int path_is_correct_directory (char *path)
{
    size_t  szPath          = 0U;

    if(path == NULL)
        return -1;
    if(*path == '\0')
        return -2;

    szPath = strlen(path);

    if(szPath < 3 || szPath > MAX_PATH)
        return -3;

    char    driveLetter[3]      = { path[0], path[1], '\0' };
    BOOL    validDriveLetter    = PathIsDirectory(driveLetter);

    if(validDriveLetter == 0)
        return -4;

    if(path[2] != '\\')
        return -5;

    int i;
    for(i = 3; i < szPath; i++)
    {
        if(path[i] == '/')  return -6;
        if(path[i] == ':')  return -7;
        if(path[i] == '*')  return -8;
        if(path[i] == '"')  return -9;
        if(path[i] == '<')  return -10;
        if(path[i] == '>')  return -11;
        if(path[i] == '|')  return -12;
        if(path[i] == '?')  return -13;
    }

    if(PathIsDirectory(path))
        return 1;

    return 0;
}


117
0
задан 16 марта 2018 в 01:03 Источник Поделиться
Комментарии
1 ответ

Магия чисел

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

path_is_correct_directory(some_path)

и вам -6что именно я сделал не так? Мне нужно смотреть в документации, проверьте значения ошибки и добавить, что мой собственный код:

if(path_is_correct_directory(some_path) == -6) {
yell_at_user("Path may not contain slash!");
}

Но это по-прежнему непрозрачны. Вместо этого, используйте enum:

enum RESULTS {
PATH_IS_VALID = 0,
PATH_IS_DIRECTORY = 1,
/* --- */
PATH_IS_NULL = -1,
PATH_IS_EMPTY = -2,
PATH_TOO_SHORT = -3,
/* --- */
INVALID_DRIVE = -4,
INVALID_DRIVE_DELIMITER = -5,
/* --- */
PATH_CONTAINS_SLASH = -6,
PATH_CONTAINS_COLON = -7,
PATH_CONTAINS_ASTERISK = -8,
PATH_CONTAINS_QUOTE = -9,
PATH_CONTAINS_LT = -10,
PATH_CONTAINS_GT = -11,
PATH_CONTAINS_PIPE = -12,
PATH_CONTAINS_QUESTION_MARK = -13
};

Вместо магических чисел, сейчас я могу с уверенностью сравнить с милым названием:

if(path_is_correc_directory(some_path) == PATH_IS_DIRECTORY) {
list_directory_contents(some_path);
}

Сохранить область действия переменных короткое

Поскольку вы используете стандарте C99, вы можете сохранить объем ваших переменных короче. Например i должны быть действительны в интернет for петли, а не снаружи. szPath может быть инициализирована с strlen сразу же (после NULL проверить).

Переменные, которые не должны меняться можно const

Все szPath, path driveLetter и validDriveLetter не должна измениться и, следовательно, может быть изменено, чтобы const.

sz префикс для строк, а не чисел

В венгерской нотации sz это префикс "сТринг расторгнут по зеро". Поскольку венгерская нотация используется в Windows API-интерфейсы, которые могут быть источником путаницы. path_size хорошо с другой стороны.

Все сразу

int path_is_correct_directory (const char *path)
{
if(path == NULL)
return PATH_IS_NULL;
if(*path == '\0')
return PATH_IS_EMPTY;

const size_t path_size = strlen(path);

if(path_size < 3 || path_size> MAX_PATH)
return PATH_TOO_SHORT;

const char driveLetter[3] = { path[0], path[1], '\0' };
const BOOL validDriveLetter = PathIsDirectory(driveLetter);

if(validDriveLetter == 0)
return INVALID_DRIVE;

if(path[2] != '\\')
return INVALID_DRIVE_DELIMITER;

for(int i = 3; i < path_size; i++)
{
if(path[i] == '/') return PATH_CONTAINS_SLASH;
if(path[i] == ':') return PATH_CONTAINS_COLON;
if(path[i] == '*') return PATH_CONTAINS_ASTERISK;
if(path[i] == '"') return PATH_CONTAINS_QUOTE;
if(path[i] == '<') return PATH_CONTAINS_LT;
if(path[i] == '>') return PATH_CONTAINS_GT;
if(path[i] == '|') return PATH_CONTAINS_PIPE;
if(path[i] == '?') return PATH_CONTAINS_QUESTION_MARK;
}

if(PathIsDirectory(path))
return PATH_IS_DIRECTORY;

return PATH_IS_VALID;
}

Кстати, Windows также поддерживает сетевые каталоги, которые начинаются с \\.

2
ответ дан 27 октября 2018 в 08:10 Источник Поделиться