【问题标题】:C++ System(); function not working as expected / Windows console commands in C++C++ 系统();函数未按预期工作/C++ 中的 Windows 控制台命令
【发布时间】:2021-07-11 14:58:55
【问题描述】:

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

我目前正在使用 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" is not写对了还是找不到”。

我不明白为什么控制台在手动插入时接受命令,但在使用 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: 时,这不起作用。

最诚挚的问候

扎戈

【问题讨论】:

  • 这总是由于不正确的引用/间距/转义。您需要了解:1)您的操作系统外壳如何解析命令,2)system 如何执行给定的命令,3)需要如何转义文字字符串以表示特殊字符。您的问题有些乱码,很难确切地看到您的代码是什么样的。无论如何,您应该能够在您的教科书中找到上述所有信息。您的教科书中是否有关于这个主题的具体内容不清楚?
  • 哈,我刚刚对 Windows 传递参数的方式大喊大叫 here。多么合适。
  • 你好山姆,谢谢你的回答。抱歉我的问题乱码,我是这个论坛的新手。我不是教科书的工作。我理解 System() 的方式; c++ 中的功能是它只是用给定的命令(在我的例子中是控制台)调用主机环境的命令处理器。所以我认为直接在控制台中插入时有效的任何命令也应该适用于 system();只要您确保字符串格式正确。但我认为这个假设是错误的(否则它会起作用)。我将在没有额外反斜杠的情况下注释我的代码:
  • @sam-varshavchik 我尝试使用一些格式化功能来减少问题的乱码
  • @peter-reinstate-monica 很好,确实很合适。但老实说,我几乎不理解你的评论,因为我对 Windows 缺乏了解,我猜......所以我真的不知道这如何帮助我修复我的代码

标签: c++ arduino windows-console avrdude


【解决方案1】:

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

开头没问题。路径被正确引用(双引号,由 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!

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

【讨论】:

  • @peter-reinstate-monica:嘿,彼得,感谢您的帮助!不知何故,这奏效了。通过使用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/Lennart/AppData/Local/Temp/arduino_build_833906/EPaper_TestDither.ino.hex:i");,我可以上传我的草图。但是由于某种原因,当使用C:\Program Files(x86)\Arduino\hardware\tools\avr\bin 而不是H: 时,这不起作用
  • 另外我不完全确定为什么我需要按照我的方式放置'"'才能工作。为什么它适用于 H:/ 但不适用于 C:/ 中的路径老实说,我不明白。删除“H:/”并将其插入根目录并停止工作。
  • 我很高兴它有帮助。我进一步调查后发现system("showargs 1 \"2 3\""); 有效,而system("\"showargs\" 1 \"2 3\"");(程序名称周围的额外引号)不起作用错误消息为'showargs" 1 "2' is not recognized as...,表明第一个转义的双引号被吞下,因此第二个是作为带引号的字符串的 start 并与它之前和之后的内容连接。如果路径有空格,则“单词”在此处结束。这类似于您的用例。-- 很好,您可以使用它!
  • @peter-reinstate-monica 再次,非常感谢!我很高兴我让它工作,即使我更喜欢不需要 H:/ 的解决方法,但也许我会解决这个问题,我肯定会尝试更多地更改语法。从理论上讲,我还需要在没有 IDE 的情况下编译草图,但我不得不承认,对于我的机械工程师大脑来说,这太多了,至少现在是这样! Ich wünsche Ihnen in jeden Fall ein schönes Wochenende!
猜你喜欢
  • 2016-09-29
  • 1970-01-01
  • 1970-01-01
  • 2018-04-10
  • 1970-01-01
  • 2017-10-21
  • 2018-11-29
  • 1970-01-01
  • 2015-06-24
相关资源
最近更新 更多