使用 strcpy 交换元素在数组中不起作用

Swapping the element using strcpy not working in the array

我试图交换数组中的元素(这是非常基本的,但是当我尝试更改数组的索引时,它弄乱了整个数组)

#include <string.h>
#include <stdio.h>
int     main(int argc, char **argv)
{
    int swap;
    int position;
    char temp[1000];
    char *i;
    swap = 1;

    while (swap == 1)
    {
        swap = 0;
        position = 1;
        while (position < (argc - 1))
        {
            if (strcmp(argv[position], argv[position + 1]) > 0)
            {
                strcpy(temp, argv[position + 1]);
                strcpy(argv[position], argv[position + 1]);
                strcpy(argv[position + 1], temp);
            }
            position++;
        }
    }
    return (0);
}

从上面的代码中,如果我输入 "hi" 和 "hello",而不是打印 "hello""hi",带来了"hello""lo",超级诡异。

然而,当我只是简单地使用指针(下面的代码)时,它工作得很好。

#include <string.h>
#include <stdio.h>
int     main(int argc, char **argv)
{
    int swap;
    int position;
    char temp[1000];
    char *i;
    swap = 1;

    while (swap == 1)
    {
        swap = 0;
        position = 1;
        while (position < (argc - 1))
        {
            if (strcmp(*(argv + position), *(argv +position + 1)) > 0 )
            {
                i = *(argv + position);
                *(argv + position) = *(argv + (position + 1));
                *(argv + position + 1) = i;
                swap = 1;
            }
            position++;
        }
    }
    return (0);
}

你能告诉我第一种做法有什么问题吗?

argv 向量指向的参数通常结构如下:

"foo[=10=]barbaz[=10=]quux[=10=]"

argv[1]指向"f",argv[2]指向"b",argv[3]指向"q"。

现在你可以很容易地看到,如果你天真地交换参数和指向它们的指针,你就会搞砸;例如,如果交换 "foo" 和 "barbaz",它看起来像这样:

"barbaz[=11=]foo[=11=]quux[=11=]".

很好,但现在 argv[2] 仍然指向同一个位置,即 barbaz 中的第二个 "a"!

您的第一种方法存在更多缺陷,因为您使用 argv 向量中的指针作为目标。首先,您将 foo 复制到 argv[2]:

"foo[=12=]foo[=12=]az[=12=]quux[=12=]"

然后barbazargv[1]

"barbaz[=13=][=13=]az[=13=]quux[=13=]"

你看,这完全是一团糟。

这就是为什么您的方法在不调整 argv-向量中的指针的情况下无法工作的原因。

您提出的第二种方法应该确实可以完美运行。

除了@Ctx 关于 *argv[] 布局的回答之外,您的数组索引还有一个问题:

索引错误:

        {
            strcpy(temp, argv[position + 1]);  // You store from index +1
            strcpy(argv[position], argv[position + 1]);
            strcpy(argv[position + 1], temp);  // Restore into same index.
        }

当您存储和恢复相同的索引时,复制到 temp 在这里没有任何效果。你最终得到了同一个字符串的两个副本。

正确索引:

        if (strcmp(*(argv + position), *(argv +position + 1)) > 0 )
        {
            i = *(argv + position);  // <<== Store from pos
            *(argv + position) = *(argv + (position + 1));
            *(argv + position + 1) = i; // <<== Restore into pos+1
            swap = 1;
        }

您存储 position 并恢复到 position + 1。这就是交换的工作原理。