首页 > 解决方案 > 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.",大致翻译为“The Command "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:.

最亲切的问候

扎戈

标签: c++arduinowindows-consoleavrdude

解决方案


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

开头还行。路径被正确引用(双引号,由 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 安装路径,您可以使用 DOSsubst命令创建一个根目录为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<-


推荐阅读