c - 将 char* 转换为 uint16_t 的安全且便携的方法

标签 c char integer

如标题中所述,我正在寻找一种将 char*(来自 argv)转换为 uint16_t 的方法。命令行参数是端口号,因此不能大于 65535,也不能为负数。

目前,我这样做了(使用 -std=gnu99 编译):

#include <stdbool.h>
#include <errno.h>
#include <stdint.h>
#include <inttypes.h>

/*
 * Converts a string to an unsigned int and stores the result in "res".
 */
bool str_to_uint(const char* str, unsigned long int* res) {
    if (str[0] == '-')
        return false;
    char* first_wrong_character;
    uintmax_t result = strtoumax(str, &first_wrong_character, 10);
    if ((result == UINTMAX_MAX) && (errno == ERANGE))
        return false; // Overflow)
    if ((*str != '\0') && (*first_wrong_character != '\0'))
        return false; // Not everything has been converted
    if ((result == 0) && (str == first_wrong_character))
        return false; // Nothing to convert
    *res = result;
    return true;
}

/*
 * Converts a string to an uint16_t and stores the result in "res".
 */
bool str_to_uint16(const char* str, uint16_t* res) {
    unsigned long uint;
    if (!str_to_uint(str, &uint))
        return false;
    if (uint > UINT16_MAX)
        return false;
    *res = (uint16_t)uint;
    return true;
}

我不确定这是最好的方法,所以你能告诉我什么是好方法吗?

最佳答案

不需要使用strtoumax。我会选择更便携的 strtol。错误处理也可以简化成这样:

bool str_to_uint16(const char *str, uint16_t *res) {
    char *end;
    errno = 0;
    long val = strtol(str, &end, 10);
    if (errno || end == str || *end != '\0' || val < 0 || val >= 0x10000) {
        return false;
    }
    *res = (uint16_t)val;
    return true;
}

关于c - 将 char* 转换为 uint16_t 的安全且便携的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20019786/

相关文章:

java - 在没有 If 语句的情况下在 Java 中将 boolean 值转换为整数

c++ - 通过 Tcp 套接字发送文件大小

c - 国际化C程序

c++ - 进程内存映射(Linux Windows)

c - *str 和 *str++

c++ - 将 char 指针存储在 vector 中

PHP char 类型加密

c - 使用 ipcrm 删除共享内存 linux

c - strncpy & 使用非空终止字符串读取堆栈帧

c - 我正在尝试编写一个 C 程序来打印整数的字符串形式。