不应该*argv[1]返回数组中第二个字符的值吗?
看签名:
int main(int argc, char *argv[])
这里,argv 是一个 数组 ([]),由 指针 (*) 到 char。所以argv[1] 是这个数组中的第二个指针。它指向命令行中给出的 first 参数。 argv[0] 保留给程序本身的名称。虽然这也可以是任何字符串,但程序的名称按照惯例放在那里(shell 会这样做)。
如果你只是取消引用一个指针,你会得到它指向的值,所以*argv[1] 会给你第一个参数的第一个字符。你可以写成argv[1][0],它们是等价的。要获取第一个参数的 第二个 字符,您可以编写 argv[1][1]。
这里要注意的重要一点是,您永远不能将数组传递给 C 中的函数。上面的签名显示了数组类型,但 C 会在函数声明中自动将数组类型调整为指针类型.这导致以下声明:
int main(int argc, char **argv)
C 中的索引运算符 ([]) 根据指针算法工作:a[x] 等价于 *(a+x)。数组的标识符被评估为指向第一个数组元素的指针在大多数情况下(例外包括sizeof 运算符)。因此,无论a 是数组还是指针,索引的工作原理都是一样的。这就是为什么您可以将argv 视为非常类似于数组的原因。
解决您的“核心”问题:argv 中总是会有 字符串,并且您需要数字输入,这意味着您必须将字符串转换为数字。已经有这样做的功能。一个很简单的就是atoi(),你可以这样使用:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
if (argc != 2)
{
// use program name in argv[0] for error message:
fprintf(stderr, "Usage: %s [number]\n", argv[0]);
return EXIT_FAILURE;
}
int i = atoi(argv[1]);
printf("Argument is %d.\n", i);
return EXIT_SUCCESS;
}
如果参数不能被解析为数字,这会给你0,如果它溢出你的int,它会给你一些不确定的值。如果您必须确保参数 是 一个有效的整数,您可以改用strtol()(注意它转换为long,而不是int,它可以处理不同的基数,所以我们必须通过10 来表示十进制):
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
int main(int argc, char **argv)
{
if (argc != 2)
{
// use program name in argv[0] for error message:
fprintf(stderr, "Usage: %s [number]\n", argv[0]);
return EXIT_FAILURE;
}
errno = 0; // reset error number
char *endptr; // this will point to the first character not read by strtol
long i = strtol(argv[1], &endptr, 10);
if (errno == ERANGE)
{
fprintf(stderr, "This number is too small or too large.\n");
return EXIT_FAILURE;
}
else if (endptr == argv[1])
{
// no character was converted. This also catches the case of an empty argument
fprintf(stderr, "The argument was not a number.\n");
return EXIT_FAILURE;
}
else if (*endptr)
{
// endptr doesn't point to NUL, so there were characters not converted
fprintf(stderr, "Unexpected characters in number.\n");
return EXIT_FAILURE;
}
printf("You entered %ld.\n", i);
return EXIT_SUCCESS;
}