C++系统();函数未按预期工作/C++ 中的 Windows 控制台命令

问题描述

您好,堆栈溢出的友好人士!

我目前正在使用 Arduino Uno 开展一个项目。因为我使用 C++ 程序创建所有文件和草图,所以我想从我的工作流程中消除 Arduino IDE。为此,我可以非常轻松地使用 avrdude(IDE 无论如何都会使用它)和一些 Windows 控制台命令。 这些是我正在使用的命令:

"C:\Program Files (x86)\Arduino\hardware\tools\avr/bin/avrdude" "-CC:\Program Files (x86)\Arduino\hardware\tools\avr/etc/avrdude.conf" -v -patmega328p -carduino -PCOM4 -b115200 -D -Uflash:w:C:\Users\Jzargo\AppData\Local\Temp\arduino_build_766345/EPaper_TestDither.ino.hex:i

“EPaper_TestDither.ino”是我要编译和上传的arduino Sketch。使用控制台并手动插入上述命令时,一切正常。

这是我正在努力解决的部分:

因为我也不希望用户手动打开控制台并输入一些乱码,所以我想使用 system() 将此命令集成到我的 C++ 程序中;功能

system("\"C:\\Program Files(x86)\\Arduino\\hardware\\tools\\avr/bin/avrdude\" \" - CC:\\Program Files(x86)\\Arduino\\\hardware\\tools\\avr/etc/avrdude.conf\" -v -patmega328p -carduino -PCOM4 -b115200 -D -Uflash:w:C:\\Users\\Jzargo\\AppData\\Local\\Temp\\arduino_build_766345/EPaper_TestDither.ino.hex:i");

执行此函数时,命令无法执行,因为“Der Befehl "C:\Program" ist entweder falsch geschrieben oder konnte nicht gefunden werden.”,大致翻译为“命令“C:\Program”不是写得正确或找不到”。

我不明白为什么控制台在手动插入时接受命令,而在使用 system() 时不接受;功能

希望你能帮我解决这个问题。

编辑:通过使用 subst H: "C:\Program Files(x86)\Arduino\hardware\tools\avr\bin"

system("\"H:/avrdude \"-CC:/Program Files (x86)/Arduino/hardware/tools/avr/etc/avrdude.conf\"\" -v -patmega328p -carduino -PCOM4 -b115200 -D -Uflash:w:C:/Users/Jzargo/AppData/Local/Temp/arduino_build_833906/EPaper_TestDither.ino.hex:i");

我可以上传我的草图。请注意 \" 的更改位置。

但由于某种原因,当使用 C:\Program Files(x86)\Arduino\hardware\tools\avr\bin 而不是 H: 时,这不起作用。

最诚挚的问候

J'zargo

解决方法

该命令在参数方面看起来很混乱,尽管我不知道这究竟是如何触发您的特定错误的。

开头还行。路径被正确引用(双引号,由 C 编译器的反斜杠保护)。但是为什么要混合使用斜杠和反斜杠呢?在一些在线示例中,我看到人们在 Windows 路径 (C:/whatever...) 中使用正斜杠;这似乎有效,而且比一直使用双反斜杠更容易(但它不应触发您的或任何错误)。

所以 system("\"C:\\Program Files(x86)\\Arduino\\hardware\\tools\\avr/bin/avrdude\" ... 应该调用正确的可执行文件。为什么不单独尝试(不带参数)以查看错误是否仍然存在?

我怀疑 \" - CC:\\Program Files(x86)\\ ... 是不正确的。 avrdude 需要参数 -C<path>,而不是 - C<path>(注意破折号前后放置的空格)。

顺便说一句,引用包含有趣字符(例如可能具有特殊含义的冒号)的参数可能不会有什么坏处。

针对此类问题的一般建议:

  • 在不包含空格、括号或其他非标识符字符的路径中工作。如果您不想更改 avrdude 安装路径,您可以使用 DOS subst 命令创建一个根为 C:\Program Files(x86) 甚至 C:\Program Files(x86)\Arduino\hardware\tools\avr\bin 的驱动器,例如subst H: "C:\Program Files(x86)\Arduino\hardware\tools\avr\bin"。该命令将是 H:/avrdude :-).
  • 如果遇到您不理解的错误,请从根本上简化问题,直到玩具版本正常运行;然后一点一点地增加复杂度,直到遇到错误;这样应该可以更轻松地识别触发它的原因。

编辑:我不确定这个例子是否有效,因为我使用了 msys2 开发环境并在 bash shell 中运行了这个例子;我什至不确定 cmd 是否被 syste 调用称为系统外壳!

为了检查系统调用语义,我编写了以下最小示例(使用混合斜杠/反斜杠作为测试)。当前目录有一个名为“some dir”的子目录,其中包含一个最小程序 showargs,它只是将其命令行参数写入标准输出:

$ ls -l "some dir" && echo && cat cmdline.c && echo && gcc -o cmdline cmdline.c && ./cmdline.exe
total 56
-rwxr-xr-x 1 Peter None 56097 Apr 16 17:23 showargs.exe

#include <stdlib.h>
int main(int argc,char **argv)
{
        system("\".\\some dir/showargs\" 1 2 3");
}

->.\some dir/showargs<-
->1<-
->2<-
->3<-

罢工>

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...