Как безопасно выйти из строки из C++

Я пишу простую программу, чтобы просмотреть локальную сеть и передать имена файлов mplayer использование "системы". Однако иногда имена файлов содержат пробелы или кавычки. Очевидно, я мог записать свою собственную функцию для выхода из них, но я не уверен точно, какие символы делают или не нужны в выходе.

Существует ли функция, доступная в CRT или где-нибудь в заголовках Linux для безопасного выхода из строки для передачи командной строке?

5
задан Chris Upchurch 8 April 2009 в 19:16
поделиться

3 ответа

Нет единого решения, которое работает везде, потому что различные оболочки имеют различные идеи того, что специальные символы и как они интерпретируются. Для удара Вам могло, вероятно, сойти с рук окружение всего имени файла в одинарных кавычках после замены каждой кавычки в имени файла с '"'"' (первая одинарная кавычка останавливает последовательность, "'" добавляет литеральную одинарную кавычку к строке, заключительная одинарная кавычка запускает заключенную в кавычки последовательность снова). Лучшее решение состояло бы в том, чтобы найти способ назвать программу, не используя систему, такой как при помощи ветвления с одной из исполнительных функций, таким образом, нет никакой интерполяции оболочки.

7
ответ дан 18 December 2019 в 09:10
поделиться

Другие ответы включают это ветвление и исполнительное решение, но я утверждаю, что это - единственный правильный способ сделать это.

Выход из аргументов оболочки подвержен ошибкам и пустой трате времени, так же, как пытающийся выйти из параметров SQL глупая идея, когда более безопасные и более эффективные API привязки параметров существуют.

Вот демонстрационная функция:

void play(const char *path)
{
    /* Fork, then exec */
    pid = fork();

    if( pid < 0 ) { 
        /* This is an error! */
        return;
    }   

    if( pid == 0 ) { 
        /* This is the child */
        freopen( "/dev/null", "r", stdin );
        freopen( "/dev/null", "w", stdout );
        freopen( "/dev/null", "w", stderr );

        execlp( "mplayer", "mplayer", path, (char *)0 );
        /* This is also an error! */
        return;
    }
}
8
ответ дан 18 December 2019 в 09:10
поделиться

В то время как я не знаю функции, которая делает это, можно окружить каждый из споров с '...', и замените любого ' в исходном аргументе '"'"' . как system("mplayer 'foo'\"'\"' bar'"); даст отдельный аргумент mplayer, который является foo'bar и которому позволяют содержать странные вещи как " или \n . Отметьте выход прежде " выше (\") только для создания этого допустимым C++.

Необходимо рассмотреть использование функции, которая принимает аргументы, которые каждый разделяет, таким образом избегая таких проблем. Википедия имеет хорошую статью об этом об известном шаблоне ветвления-и-должностного-лица. http://en.wikipedia.org/wiki/Fork-exec

3
ответ дан 18 December 2019 в 09:10
поделиться