C ++ system () не работает, когда есть пробелы в двух разных параметрах - PullRequest
13 голосов
/ 01 апреля 2012

Я пытаюсь запустить .exe, для которого требуются некоторые параметры, с помощью system ().

Если в пути к файлу .exe И в пути к файлу, переданному в параметрах, есть пробел, я получаю следующую ошибку:

The filename, directory name, or volume label syntax is incorrect.

Вот код, который генерирует эту ошибку:

#include <stdlib.h>
#include <conio.h>

int main (){
    system("\"C:\\Users\\Adam\\Desktop\\pdftotext\" -layout \"C:\\Users\\Adam\\Desktop\\week 4.pdf\"");
    _getch();
}

Если путь "pdftotext" не использует кавычки (они нужны мне, потому что иногда в каталоге будут пробелы), все работает нормально. Кроме того, если я помещаю то, что в "system ()", в строку и выводю ее, а затем копирую в фактическое командное окно, это работает.

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

cd C:\Users\Adam\Desktop;
pdftotext -layout "week 4.pdf"

Так что я уже был бы в правильном каталоге, но я не знаю, как использовать несколько команд в одной и той же функции system ().

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

Редактировать: Похоже, мне нужен был дополнительный набор кавычек, потому что system () передает свои аргументы в cmd / k, поэтому он должен быть в кавычках. Я нашел это здесь:

C ++: Как заставить мою программу открывать .exe с необязательными аргументами

поэтому я проголосую за закрытие как дубликат, так как вопросы довольно близки, хотя мы не получили одно и то же сообщение об ошибке, спасибо!

Ответы [ 3 ]

28 голосов
/ 01 апреля 2012

system() запускает команду как cmd /C command.А вот цитата из cmd doc:

If /C or /K is specified, then the remainder of the command line after
the switch is processed as a command line, where the following logic is
used to process quote (") characters:

    1.  If all of the following conditions are met, then quote characters
        on the command line are preserved:

        - no /S switch
        - exactly two quote characters
        - no special characters between the two quote characters,
          where special is one of: &<>()@^|
        - there are one or more whitespace characters between the
          two quote characters
        - the string between the two quote characters is the name
          of an executable file.

    2.  Otherwise, old behavior is to see if the first character is
        a quote character and if so, strip the leading character and
        remove the last quote character on the command line, preserving
        any text after the last quote character.

Кажется, что вы попали в случай 2, а cmd считает, что вся строка C:\Users\Adam\Desktop\pdftotext" -layout "C:\Users\Adam\Desktop\week 4.pdf (т.е. без первой и последней кавычек)имя исполняемого файла.

Таким образом, решение было бы заключить команду в дополнительные кавычки:

//system("\"D:\\test\" nospaces \"text with spaces\"");//gives same error as you're getting
system("\"\"D:\\test\" nospaces \"text with spaces\"\""); //ok, works

И это очень странно.Я думаю, что это также хорошая идея добавить /S, просто чтобы убедиться, что он всегда будет анализировать строку в случае 2: ​​

system("cmd /S /C \"\"D:\\test\" nospaces \"text with spaces\"\""); //also works
0 голосов
/ 12 апреля 2019

Я пришел сюда в поисках ответа, и это был код, который я придумал (и я был таким явным для удобства следующего человека, поддерживающего мой код):

std::stringstream ss;
std::string pathOfCommand;
std::string pathOfInputFile;

// some code to set values for paths

ss << "\"";                             // command opening quote
ss << "\"" << pathOfCommand   << "\" "; // Quoted binary (could have spaces)
ss << "\"" << pathOfInputFile << "\"";  // Quoted input (could have spaces)
ss << "\"";                             // command closing quote
system( ss.str().c_str() );             // Execute the command

и это решило все мои проблемы.

0 голосов
/ 06 июня 2018

Хорошие знания отсюда по внутренним системным вызовам. Та же проблема воспроизводима (конечно) с помощью строки C ++, TCHAR и т. Д. Один подход, который всегда помог мне, - это вызов SetCurrentDirectory (). Сначала я устанавливаю текущий путь, а затем выполняю. Это сработало для меня до сих пор. Любые комментарии приветствуются. -Sreejith. Д. Менон

...