如何获取 argv 并将其转换为 uint16_t
How to take a argv and convert it to uint16_t
我需要获取一个参数 (argv[2]) 并将其转换为 uint16_t 类型。我怎么能得到这个?
我在参数中放置了一个端口,所以我需要在 uint16_t 中进行转换,我试过这个:
uint16_t PORT;
PORT = argv[2];
但是当我这样做时
servaddr.sin_port = htons(PORT)
我明白了
warning: assignment makes integer from pointer without a cast
您可以通过 atoi()
函数将 char *
转换为 int
(因此,转换为 uint16_t
):
#include <stdlib.h>
[...]
uint16_t PORT = atoi(argv[2]);
你需要使用the strtoul()
function,一个快速的方法是这样的:
errno = 0;
uint16_t PORT = strtoul(argv[2], NULL, 0);
if ( errno != 0 )
{
//invalid input
}
一种更稳健的方法是使用中间 unsigned long
值并检查它是否包含适合 16 位端口的值。
有关更多详细信息,请参阅 。
永远不要使用 atoi()
。它无法 return 任何错误条件,如果您向它传递一些无效输入,它会调用未定义的行为。
How to take a argv
and convert it to uint16_t
(?)
argv[i]
可能指向一个 字符串 。然后任务是将该字符串转换为 uint16_t
.
OP 的代码失败,因为下面更像是获取字符串的 地址 并将其转换为可能被截断的 16 位值。
uint16_t PORT;
PORT = argv[2]; // poor code
确保有效argv[2]
int main(int argc, char *argv[]) {
if (argc <= 2) {
fprintf(stderr, "argv[2] missing.\n");
return EXIT_FAILURE;
}
...
处理非数字输入
在 "abc"
、"123abc"
、"-123"
、""
、" "
、" 123 "
、[=24 等情况下应该发生什么=]、"123456"
、"123456789012345678901234567890"
、"0x123"
、"-0"
、"0.0"
等?
通常的目标是慷慨地允许领先的白色-space 和尾随的 WS(即使这样的 WS 在 argv[]
中并不常见)。抱怨超出范围 [0...65535] 的值。抱怨其他非整数数字,非白色-space字符。
strtoul()
是一个良好的开端,其定义明确的错误处理。
当输入格式不正确或 int
为 16 位时,atoi()
无法很好地转换为 uint16_t
。
我不喜欢 strtoul()
的一个属性是 '-'
在转换后应用,因此 "-1"
可以输入,returns ULONG_MAX
。我宁愿将其检测为错误。由于 long
的范围总是比 uint16_t
宽,如果代码应该将负值检测为错误,我建议 strtol()
。
样本
char *endptr;
errno = 0;
long value = strtol(argv[2], &endptr, 0);
if (errno) { // This test not certainly needed here as later test will catch
perror("argv[2] error");
return EXIT_FAILURE;
}
if (argv[2] == endptr) { // No conversion happened
fprintf(stderr, "argv[2] <%s> non-numeric\n", argv[2]);
return EXIT_FAILURE;
}
if (value < 0 || value > UINT16_MAX) {
fprintf(stderr, "argv[2] %ld outside uint16_t range\n", value);
return EXIT_FAILURE;
}
while (isspace((unsigned char) *endptr)) {
endptr++;
}
if (*endptr) {
fprintf(stderr, "argv[2] <%s> trailing non-numeric text\n", argv[2]);
return EXIT_FAILURE;
}
PORT = (uint16_t) value; // Cast to quiet conversion warning
printf("argv[2] --> %u success\n", PORT);
return EXIT_SUCCESS;
}
这个冗长的代码最好作为辅助函数合并,而不是为每个 字符串 到 uint16_t
复制。但我怀疑 OP 稍后会使用这些功能。
我需要获取一个参数 (argv[2]) 并将其转换为 uint16_t 类型。我怎么能得到这个? 我在参数中放置了一个端口,所以我需要在 uint16_t 中进行转换,我试过这个:
uint16_t PORT;
PORT = argv[2];
但是当我这样做时
servaddr.sin_port = htons(PORT)
我明白了
warning: assignment makes integer from pointer without a cast
您可以通过 atoi()
函数将 char *
转换为 int
(因此,转换为 uint16_t
):
#include <stdlib.h>
[...]
uint16_t PORT = atoi(argv[2]);
你需要使用the strtoul()
function,一个快速的方法是这样的:
errno = 0;
uint16_t PORT = strtoul(argv[2], NULL, 0);
if ( errno != 0 )
{
//invalid input
}
一种更稳健的方法是使用中间 unsigned long
值并检查它是否包含适合 16 位端口的值。
有关更多详细信息,请参阅
永远不要使用 atoi()
。它无法 return 任何错误条件,如果您向它传递一些无效输入,它会调用未定义的行为。
How to take a
argv
and convert it touint16_t
(?)
argv[i]
可能指向一个 字符串 。然后任务是将该字符串转换为 uint16_t
.
OP 的代码失败,因为下面更像是获取字符串的 地址 并将其转换为可能被截断的 16 位值。
uint16_t PORT;
PORT = argv[2]; // poor code
确保有效argv[2]
int main(int argc, char *argv[]) {
if (argc <= 2) {
fprintf(stderr, "argv[2] missing.\n");
return EXIT_FAILURE;
}
...
处理非数字输入
在 "abc"
、"123abc"
、"-123"
、""
、" "
、" 123 "
、[=24 等情况下应该发生什么=]、"123456"
、"123456789012345678901234567890"
、"0x123"
、"-0"
、"0.0"
等?
通常的目标是慷慨地允许领先的白色-space 和尾随的 WS(即使这样的 WS 在 argv[]
中并不常见)。抱怨超出范围 [0...65535] 的值。抱怨其他非整数数字,非白色-space字符。
strtoul()
是一个良好的开端,其定义明确的错误处理。
int
为 16 位时,atoi()
无法很好地转换为 uint16_t
。
我不喜欢 strtoul()
的一个属性是 '-'
在转换后应用,因此 "-1"
可以输入,returns ULONG_MAX
。我宁愿将其检测为错误。由于 long
的范围总是比 uint16_t
宽,如果代码应该将负值检测为错误,我建议 strtol()
。
样本
char *endptr;
errno = 0;
long value = strtol(argv[2], &endptr, 0);
if (errno) { // This test not certainly needed here as later test will catch
perror("argv[2] error");
return EXIT_FAILURE;
}
if (argv[2] == endptr) { // No conversion happened
fprintf(stderr, "argv[2] <%s> non-numeric\n", argv[2]);
return EXIT_FAILURE;
}
if (value < 0 || value > UINT16_MAX) {
fprintf(stderr, "argv[2] %ld outside uint16_t range\n", value);
return EXIT_FAILURE;
}
while (isspace((unsigned char) *endptr)) {
endptr++;
}
if (*endptr) {
fprintf(stderr, "argv[2] <%s> trailing non-numeric text\n", argv[2]);
return EXIT_FAILURE;
}
PORT = (uint16_t) value; // Cast to quiet conversion warning
printf("argv[2] --> %u success\n", PORT);
return EXIT_SUCCESS;
}
这个冗长的代码最好作为辅助函数合并,而不是为每个 字符串 到 uint16_t
复制。但我怀疑 OP 稍后会使用这些功能。