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

C++ System(); function not working as expected / Windows console commands in C++

堆栈溢出的朋友们您好!

我目前正在使用 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: 时,这不起作用。

最诚挚的问候

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 调用为系统 shell!

为了检查系统调用语义,我编写了以下最小示例(使用混合 slashes/backslashes 作为测试)。当前目录有一个名为“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<-