【问题标题】:Cannot sort command line arguments using strcpy无法使用 strcpy 对命令行参数进行排序
【发布时间】:2017-09-14 02:50:43
【问题描述】:

我是 C/C++ 的新手,我正在学习命令行参数。我正在尝试使用 strcpy 对我的命令行参数进行排序,但是它给了我不好的输出。 例如


我/p:我是


o/p : 亲 我

谁能帮我解决我在这里做错了什么?请注意:我只为 argc=3 运行此程序,并且我只为上面示例中列出的输入(将被排序)运行此代码。 我刚刚删除了用于调试的循环。

#include "iostream"
#include "cstdlib"
#include "cstring"
using namespace std;

int main (int argc, char **argv) 
{

    char temp[100];

    //sorting my command line arguments
    if(strcmp(argv[1],argv[2])>0)
    {
        strcpy(temp,argv[1]);
        strcpy(argv[1],argv[2]);
        strcpy(argv[2],temp);
    }

    cout<<argv[1]<<endl;
    cout<<argv[2]<<endl;

    return 0;
}

【问题讨论】:

  • 命令行参数的大小不会自动改变,所以你不能像那样复制它们(除非它们的长度都一样)。
  • @CroCo 我首先比较字符串,并在此基础上进行交换/排序。
  • @Galik 那么如何对可变长度的参数进行排序?
  • “对 C/C++ 相当陌生”。您可以从选择两者之一开始。在 C++ 中,这是微不足道的。 std::vector&lt;std::string&gt; args(argc, argc+argv); if (args[1]&lt;args[2]) swap(args[1],args[2]);

标签: c++ command-line-arguments strcpy


【解决方案1】:

考虑您的内存布局。当你运行$ ./a.out i am时,程序启动时会是这个样子:

a   .   o  u  t  \0 i  \0 a  m  \0
^                   ^     ^
argv[0]          argv[1]  argv[2]

在您的交换过程中写入argv[1] 会将其更改为:

a   .   o  u  t  \0 a  m  \0 m  \0
^                   ^     ^
argv[0]          argv[1]  argv[2]

然后写入argv[2] 会再次变成这样:

a   .   o  u  t  \0 a  m  i  \0 \0
^                   ^     ^
argv[0]          argv[1]  argv[2]

所以当你打印出argv[1] 时,它会一直读取到空字节,给你amiargv[2] 将从不同的起点读取,为您提供i

正如 Galik 指出的那样,这是因为 argv[1]argv[2] 不是某种自动调整大小的缓冲区。它们只是指向内存的指针。在这一点上我应该注意,确切的布局不是由语言正式定义的。根据您使用的平台,您可能会遇到各种不同的不可预知的行为。

要解决此问题,您应该创建一个指向要排序的字符串的指针数组,并交换指针而不是字符串的值。这将更快(需要复制的字节更少)和更安全(意外溢出缓冲区的方式更少,如果您的输入之一长于 100 个字符,则在您当前的代码中会发生这种情况)。

【讨论】:

  • 谢谢,这绝对解决了问题。编辑:不明白为什么这个答案被否决了。顺便说一句,我已经接受了你的回答。
猜你喜欢
  • 1970-01-01
  • 2012-10-25
  • 1970-01-01
  • 2014-10-10
  • 2021-02-06
  • 2012-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多