С++ system() не работает, когда существуют пробелы в двух разных параметрах

Я пытаюсь запустить .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, поэтому он должен быть в цитатах. Я нашел его здесь:

С++: как сделать мою программу открытой .exe с дополнительными аргументами

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

Ответ 1

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

Ответ 2

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

Ответ 3

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

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

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