为什么第二个参数不适用于 strtol?
Why is the second argument not working with strtol?
我是这样做的:
/* convert the argv[1] into Integer and store the result in key
* using library function: strtol() to do it */
char **flag = NULL;
key = strtol(argv[1], flag, 10);
// if argv[1] is not all digits
if (**flag != '[=10=]')
{
printf("Usage: ./caesar key\n");
return 1;
}
但是它抛出一个分段错误。我不知道为什么。
在 C 文档中,strtol
的原型为 long int strtol(const char *nptr, char **endptr, int base)
。为什么我会出现分段错误?
并且当将代码的某些部分更改为 char *flag
、strtol(argv[1], &flag, 10)
和 if (*flag != '[=15=]')
时,一切都按预期工作。
我了解(某种程度上)进行编辑如何更正代码。但是,我不知道为什么原始代码不起作用。有人知道吗?
您需要传递您的 char *
指针的地址,以便 strtol
可以更新它。
char *flag = NULL;
key = strtol(argv[1], &flag, 10);
// if argv[1] is not all digits
if (*flag != '[=10=]')
调用后,指针将被修改为指向输入字符串解析区域的末尾。
手册页的措辞确实令人困惑。
I do not know why the original code does not work? Does anyone have any clue?
因为这里
char **flag = NULL;
flag
设为NULL
,那么这里
key = strtol(argv[1], flag, 10);
flags
的值(NULL
)传递给strtol()
,这不会以任何方式改变flags
的值,它是NULL
在调用 strtol()
.
之前和之后
终于到了
if (**flag != '[=12=]')
flag
,其值为 NULL
,被取消引用,这会调用未定义的行为,这可能导致任何事情,在您的情况下是崩溃。
考虑这个将数字乘以 2 的简单函数。
void Times2(int number, int *result)
{
*result = number * 2;
}
你应该这样称呼它:
int result;
Times2(3, &result);
printf("%d\n", result);
预期输出为 4
。
但是如果你这样调用它(这基本上就是你在错误代码中调用 strtol
时所做的):
int *result = NULL;
Times2(3, result);
printf("%d\n", result);
你的程序很可能会以段错误结束,因为在 Times2
函数中你取消引用了一个 NULL
指针。
Why second argument not working with strol
?
char **flag = NULL;
key = strtol(argv[1], flag, 10);
正在运行。传递 空指针 没问题,但 flag
不会在调用代码中更改。
当第二个参数是一个空指针时,没有关于转换结束位置的更新。
后面的代码:if (**flag != '[=16=]')
中的 *flag
是错误的(未定义的行为),因为它试图取消引用空指针。
改为传递已知指针的地址:
//char **flag = NULL;
char *flag;
//key = strtol(argv[1], flag, 10);
key = strtol(argv[1], &flag, 10);
// if (**flag != '[=11=]')
if (*flag != '[=11=]')
以下是 char*
到 int
的完整测试转换。
#include <stdlib.h>
#incluse <ctype.h>
// Return error flag
int my_strtol(long *destination, const char *s) {
if (destination == NULL) {
return 1;
}
if (s == NULL) {
*destination = 0;
return 1;
}
char *endptr;
errno = 0;
*destination = strtol(s, &endptr, 0);
// If no conversion or out-of-range
if (s == endptr || errno == ERANGE) {
return 1;
}
// I like to tolerate trailing white-space.
while (isspace(*(const unsigned char *) endptr)) {
endptr++;
}
return *endptr != '[=12=]';
}
我是这样做的:
/* convert the argv[1] into Integer and store the result in key
* using library function: strtol() to do it */
char **flag = NULL;
key = strtol(argv[1], flag, 10);
// if argv[1] is not all digits
if (**flag != '[=10=]')
{
printf("Usage: ./caesar key\n");
return 1;
}
但是它抛出一个分段错误。我不知道为什么。
在 C 文档中,strtol
的原型为 long int strtol(const char *nptr, char **endptr, int base)
。为什么我会出现分段错误?
并且当将代码的某些部分更改为 char *flag
、strtol(argv[1], &flag, 10)
和 if (*flag != '[=15=]')
时,一切都按预期工作。
我了解(某种程度上)进行编辑如何更正代码。但是,我不知道为什么原始代码不起作用。有人知道吗?
您需要传递您的 char *
指针的地址,以便 strtol
可以更新它。
char *flag = NULL;
key = strtol(argv[1], &flag, 10);
// if argv[1] is not all digits
if (*flag != '[=10=]')
调用后,指针将被修改为指向输入字符串解析区域的末尾。
手册页的措辞确实令人困惑。
I do not know why the original code does not work? Does anyone have any clue?
因为这里
char **flag = NULL;
flag
设为NULL
,那么这里
key = strtol(argv[1], flag, 10);
flags
的值(NULL
)传递给strtol()
,这不会以任何方式改变flags
的值,它是NULL
在调用 strtol()
.
终于到了
if (**flag != '[=12=]')
flag
,其值为 NULL
,被取消引用,这会调用未定义的行为,这可能导致任何事情,在您的情况下是崩溃。
考虑这个将数字乘以 2 的简单函数。
void Times2(int number, int *result)
{
*result = number * 2;
}
你应该这样称呼它:
int result;
Times2(3, &result);
printf("%d\n", result);
预期输出为 4
。
但是如果你这样调用它(这基本上就是你在错误代码中调用 strtol
时所做的):
int *result = NULL;
Times2(3, result);
printf("%d\n", result);
你的程序很可能会以段错误结束,因为在 Times2
函数中你取消引用了一个 NULL
指针。
Why second argument not working with
strol
?
char **flag = NULL;
key = strtol(argv[1], flag, 10);
正在运行。传递 空指针 没问题,但 flag
不会在调用代码中更改。
当第二个参数是一个空指针时,没有关于转换结束位置的更新。
后面的代码:if (**flag != '[=16=]')
中的 *flag
是错误的(未定义的行为),因为它试图取消引用空指针。
改为传递已知指针的地址:
//char **flag = NULL;
char *flag;
//key = strtol(argv[1], flag, 10);
key = strtol(argv[1], &flag, 10);
// if (**flag != '[=11=]')
if (*flag != '[=11=]')
以下是 char*
到 int
的完整测试转换。
#include <stdlib.h>
#incluse <ctype.h>
// Return error flag
int my_strtol(long *destination, const char *s) {
if (destination == NULL) {
return 1;
}
if (s == NULL) {
*destination = 0;
return 1;
}
char *endptr;
errno = 0;
*destination = strtol(s, &endptr, 0);
// If no conversion or out-of-range
if (s == endptr || errno == ERANGE) {
return 1;
}
// I like to tolerate trailing white-space.
while (isspace(*(const unsigned char *) endptr)) {
endptr++;
}
return *endptr != '[=12=]';
}