使用 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=]"
然后barbaz
到argv[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
。这就是交换的工作原理。
我试图交换数组中的元素(这是非常基本的,但是当我尝试更改数组的索引时,它弄乱了整个数组)
#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=]"
然后barbaz
到argv[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
。这就是交换的工作原理。